목차
쿠버네티스 설치부터 서비스 배포까지 - 1.도커 설치
쿠버네티스 설치부터 서비스 배포까지 - 2.쿠버네티스 설치
쿠버네티스 설치부터 서비스 배포까지 - 2-1. 쿠버네티스 재설치
쿠버네티스 설치부터 서비스 배포까지 - 3.쿠버네티스 Ingress Nginx 생성
쿠버네티스 설치부터 서비스 배포까지 - 4.NFS 설치
쿠버네티스 설치부터 서비스 배포까지 - 5.데이터베이스 설정
쿠버네티스 설치부터 서비스 배포까지 - 6.프론트엔드 설정
쿠버네티스 설치부터 서비스 배포까지 - 7.백엔드 설정
쿠버네티스 설치부터 서비스 배포까지 - 8.결과화면
8.결과화면
지금까지 작성한 결과에 대해서 확인하면 다음과 같습니다
master 서버에 접속하여 다음 주소로 접속합니다
http://127.0.0.1:31845
머신러닝 추론 페이지인 ML 메뉴로 이동
모델 생성
머신러닝은 Fashion MNIST 를 이용한 분류 기능을 만들어 봤습니다
CNN을 공부하며 다음과 같이 코드를 작성하여 모델을 생성하였습니다.
# -*- coding: utf-8 -*-
"""CNNTest.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1QbaPiN0k4iEsgCXa-CaqYj0aa5FM2BZ-
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
"""torch device가 cuda를 사용 할 수 있는지 확인을 하고 cuda or cpu 을 정합니다."""
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
device
"""datasets는 샘플과 정답을 저장하고 있습니다.
ex) (image, label)
transforms를 통해 정규화를 합니다. datasets에서 넘어온 FashionMNIST 데이터셋은 PIL Image로 이루어져 있습니다.
이를 Tensor 화 시킵니다.
"""
train_dataset = torchvision.datasets.FashionMNIST(root='/', train=True, download=True, transform=transforms.ToTensor())
test_dataset = torchvision.datasets.FashionMNIST(root='/', train=False, download=True, transform=transforms.ToTensor())
print(train_dataset, test_dataset)
print(len(train_dataset[0]))
# plt.imshow(train_dataset[0][0])
print(train_dataset[0][0].shape)
"""DataLoader는 dataset을 샘플에 쉽게 접근 할 수 있도록 순회 가능한 객체로 감쌉니다.
iterable = 순회 가능한 객체
"""
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=100)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=100)
print(train_loader, test_loader)
class FashionMNIST(nn.Module):
def __init__(self):
super(FashionMNIST, self).__init__()
self.conv2 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=1)
self.batchNorm2d = nn.BatchNorm2d(32)
self.relu = nn.ReLU()
self.maxPool2d = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(in_features=169*2*2*2*2*2, out_features=600)
self.drop = nn.Dropout2d(0.25)
self.fc2 = nn.Linear(in_features=600, out_features=120)
self.fc3 = nn.Linear(in_features=120, out_features=10)
def forward(self, x):
out = self.conv2(x)
out = self.batchNorm2d(out)
out = self.relu(out)
out = self.maxPool2d(out)
out = out.view(out.size(0), -1)
out = self.fc1(out)
out = self.drop(out)
out = self.fc2(out)
out = self.fc3(out)
return out
model = FashionMNIST()
model.to(device)
print(model)
learning_rate = 0.001
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
print(model.parameters())
epochs = 10
count = 0
loss_ = []
for epoch in range(epochs):
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
train = images.view(100, 1, 28, 28)
outputs = model(train)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
count += 1
if not (count % 500):
print("epoch: {}, count: {}, loss: {}".format(epoch, count, loss.data))
loss_.append(loss.item())
print(loss_)
plt.plot(loss_)
plt.title(loss)
plt.xlabel('epoch')
plt.show()
dataiter = iter(test_loader)
images, labels = dataiter.next()
print(images.shape)
print(images[0][0].shape)
plt.imshow(images[0][0])
correct = 0
total = 0
with torch.no_grad():
for data in test_loader:
images, labels = data[0].to(device), data[1].to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print(f'accuracy : {100*correct/total}%')
torch.save(model.state_dict(), '/content/drive/MyDrive/mnist.pt')
백엔드에서 모델을 기반으로 한 추론 코드 작성
class InferenceCnnAPI(APIView):
def post(self, request):
# image 파일 추출
file = request.FILES['cnn_image']
if file is None:
return '선택된 파일이 없습니다'
elif os.path.exists('k8s/assets/image/cnn.png'):
os.remove('k8s/assets/image/cnn.png')
# image 저장
fs = FileSystemStorage()
filename = fs.save('k8s/assets/image/cnn.png', file)
# 저장한 image load, 1차원으로 수정
try:
im = Image.open(filename).convert('L')
except Exception as e:
return Response('')
# PIL Image -> Tensor로 변환
t = transforms.Compose([
transforms.Resize(size=(28, 28)),
transforms.ToTensor()
])
# model parameter 맞게 차원 조정 ( 1, 1 , 28, 28 )
test_data = t(im).unsqueeze(0)
# cuda 설정
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = FashionMNIST()
model.to(device=device)
model.load_state_dict(torch.load('k8s/models/cnn.pt'))
model.eval()
out = model(test_data)
_, predicted = torch.max(out.data, 1)
output_label = {
0: 'T-shirt/Top',
1: 'Trouser',
2: 'Pullover',
3: 'Dress',
4: 'Coat',
5: 'Sandal',
6: 'Shirt',
7: 'Sneaker',
8: 'Bag',
9: 'Ankle Boot'
}
result = output_label[predicted.item()]
return Response(result)
위와 같이 머신러닝 관련해서 모델 생성 및 추론 코드를 작성하여 다음과 같이 적용했습니다.
리액트에서 이미지를 업로드하고, inference를 누르면 백엔드로 이미지를 보내서 결과를 추론하고 결과 값을 반환하여 클라리언트에게 보여주도록 했습니다.
드레스 이미지 → inference → Dress
가방 이미지 → inference → Bag
결과를 보니 잘 분류한다는 것을 확인 할 수 있습니다
데이터베이스 정상 연결 확인
dbeaver 라는 프로그램을 사용해 데이터베이스에 접근해 보면 다음과 같이 k8s_member 라는 테이블이 생성되어 있는 것을 확인 할 수 있습니다
sign-up 페이지로 이동해서 회원가입은 잘 되는지 확인해보겠습니다
데이터베이스를 확인해보니 데이터베이스로 잘 입력된 것을 확인 할 수 있습니다
이로써 쿠버네티스부터 서비스 배포까지의 제가 작성할 수준의 과정은 모두 작성하였는데요
이 과정은 기초나 다름없고 실제로 운영하기 위해서는 도커 레지스트리, 스토리 저장소, 머신러닝을 효율적으로 사용하기 위한 쿠브플로우, 쿠버네티스 인증서, 메시지 큐 등등 수 많은 기능을 덧붙이고 각각의 기능을 이어야 합니다
아주 할 일이 많죠
그래서 저도 아직 한 ~ 참 배울 것들이 많네요 ㅎㅎ
별다른 설명 없이 과정과 결과만 간략하게 작성해서 도움이 되었을지 모르겠으나
이 글을 읽고 계신 분께 그래도 조금이라도 도움이 되었길 바랍니다.
화이팅 입니다😁
'Infrastructure > Docker & Kubernetes' 카테고리의 다른 글
Dockerfile에서 bashrc 작성하기 (0) | 2023.05.25 |
---|---|
에러, Conflicting values set for option Signed-By regarding source https://download.docker.com/linux/ubuntu/ bionic: /usr/share/keyrings/docker-archive-keyring.gpg != (0) | 2022.05.05 |
쿠버네티스 설치부터 서비스 배포까지 - 7.백엔드 설정 (0) | 2022.05.05 |
쿠버네티스 설치부터 서비스 배포까지 - 6.프론트엔드 설정 (0) | 2022.05.05 |
쿠버네티스 설치부터 서비스 배포까지 - 5.데이터베이스 설정 (0) | 2022.05.05 |