Tensorflow와 scikit-learn을 주로 다루었던 나에게 pytorch는 아직 생소하기는 하다. 그렇다고 하더라도 유사한 점이 많고 과제를 하면서 많은 부분을 배울 수 있었다(부덕아 고마워,,,)
수업 내용 정리 이후, 과제에서 눈여겨 볼만 한 것은 다음 포스트로 남기고자 한다. 그럼 잡소리는 여기까지
class MyLiner(nn.Module):
def __init__(self, in_features, out_features, bias=True):
super().__init__()
self.in_features = in_features
self.out_features = out_features
self.weights = nn.Parameter( torch.randn(in_features, out_features))
self.bias = nn.Parameter(torch.randn(out_features))
def forward(self, x : Tensor):
return x @ self.weights + self.bias
class MyLiner_Tensor(nn.Module):
def __init__(self, in_features, out_features, bias=True):
super().__init__()
self.in_features = in_features
self.out_features = out_features
self.weights = Tensor( torch.randn(in_features, out_features))
self.bias = Tensor(torch.randn(out_features))
def forward(self, x : Tensor):
return x @ self.weights + self.bias
layer = Mylinear()
for value in layer.parameters():
print(value)
>> 각 파라미터들이 출력된다
layer = Mylinear_Tensor()
for value in layer.parameters():
print(value)
파라미터가 나오지 않는다(backward propagation) 대상이 아니기 때문에
for epoch in range(epochs): ......
# Clear gradient buffers because we don't want any gradient
#from previous epoch to carry forward
optimizer.zero_grad()
# get output from the model, given the inputs
outputs = model(inputs)
# get loss for the predicted output
loss = criterion(outputs, labels) print(loss)
# get gradients w.r.t to parameters loss.backward()
# update parameters
optimizer.step()
import numpy as np
# create dummy data for training
x_values = [i for i in range(11)]
x_train = np.array(x_values, dtype=np.float32)
x_train = x_train.reshape(-1, 1)
y_values = [2*i + 1 for i in x_values]
y_train = np.array(y_values, dtype=np.float32)
y_train = y_train.reshape(-1, 1)
import torch
from torch.autograd import Variable
class LinearRegression(torch.nn.Module):
def __init__(self, inputSize, outputSize):
super(LinearRegression, self).__init__()
self.linear = torch.nn.Linear(inputSize, outputSize)
def forward(self, x):
out = self.linear(x)
return out
inputDim = 1 # takes variable 'x'
outputDim = 1 # takes variable 'y'
learningRate = 0.01
epochs = 100
model = LinearRegression(inputDim, outputDim)
##### For GPU #######
if torch.cuda.is_available():
model.cuda()
else:
model.forward()
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learningRate)
# Stochastic Gradient Descent의 대상이 되는 것은 모델의 파라미터들
for epoch in range(epochs):
# 지금은 데이터가 적기 때문에 한 번 epoch 때마다 모든 데이터를 다루게 된다.
# 그러나 데이터가 많다면 dataloader를 사용해야 할 것
if torch.cuda.is_available():
inputs = Variable(torch.from_numpy(x_train).cuda())
labels = Variable(torch.from_numpy(y_train).cuda())
else:
inputs = Variable(torch.from_numpy(x_train))
labels = Variable(torch.from_numpy(y_train))
# Clear gradient buffers because we don't want any gradient
# from previous epoch to carry forward, dont want to cummulate gradients
optimizer.zero_grad()
# get output from the model, given the inputs
outputs = model(inputs)
# get loss for the predicted output
loss = criterion(outputs, labels)
print(loss)
# get gradients w.r.t to parameters
loss.backward()
# update parameters
optimizer.step()
print('epoch {}, loss {}'.format(epoch, loss.item()))
with torch.no_grad(): # we don't need gradients in the testing phase
if torch.cuda.is_available():
predicted = model(Variable(torch.from_numpy(x_train).cuda())).cpu().data.numpy()
else:
predicted = model(Variable(torch.from_numpy(x_train))).data.numpy()
print(predicted)
for p in model.parameters():
if p.requires_grad:
print(p.name, p.data)
class LR(nn.Module):
def __init__(self, dim, lr=torch.scalar_tensor(0.01)):
super(LR, self).__init__()
# intialize parameters
self.w = torch.zeros(dim, 1, dtype=torch.float).to(device)
self.b = torch.scalar_tensor(0).to(device)
self.grads = {"dw": torch.zeros(dim, 1, dtype=torch.float).to(device),
"db": torch.scalar_tensor(0).to(device)} self.lr = lr.to(device)
def forward(self, x):
## compute forward
z = torch.mm(self.w.T, x) a = self.sigmoid(z) return a
def sigmoid(self, z):
return 1/(1 + torch.exp(-z))
def backward(self, x, yhat, y):
## compute backward
self.grads["dw"] = (1/x.shape[1]) * torch.mm(x, (yhat - y).T)
self.grads["db"] = (1/x.shape[1]) * torch.sum(yhat - y)
def optimize(self):
## optimization step
self.w = self.w - self.lr * self.grads["dw"]
self.b = self.b - self.lr * self.grads["db"]
import torch
from torch.utils.data import Dataset
class CustomDataset(Dataset):
def __init__(self, text, labels):
self.labels = labels
self.data = text
def __len__(self):
return len(self.labels)
def __getitem__(self, idx): label = self.labels[idx]
text = self.data[idx]
sample = {"Text": text, "Class": label}
return sample
text = ['Happy', 'Amazing', 'Sad', 'Unhapy', 'Glum']
labels = ['Positive', 'Positive', 'Negative', 'Negative', 'Negative']
MyDataset = CustomDataset(text, labels)
text = ['Happy', 'Amazing', 'Sad', 'Unhapy', 'Glum']
labels = ['Positive', 'Positive', 'Negative', 'Negative', 'Negative']
MyDataset = CustomDataset(text, labels)
MyDataLoader = DataLoader(MyDataset, batch_size=2, shuffle=True)
next(iter(MyDataLoader))
# {'Text': ['Glum', 'Sad'], 'Class': ['Negative', 'Negative']}
MyDataLoader = DataLoader(MyDataset, batch_size=2, shuffle=True)
for dataset in MyDataLoader:
print(dataset)
# {'Text': ['Glum', 'Unhapy'], 'Class': ['Negative', 'Negative']} # {'Text': ['Sad', 'Amazing'], 'Class': ['Negative', 'Positive']} # {'Text': ['Happy'], 'Class': ['Positive']}
DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
batch_sampler=None, num_workers=0, collate_fn=None, pin_memory=False,
drop_last=False, timeout=0, worker_init_fn=None, *, prefetch_factor=2,
persistent_workers=False)
Backward, DatasetLoader, Dataset에 대해서는 다음 포스트에 다루도록 하겠다.
참고자료 : 네이버부스트캠프자료
https://pytorch.org/docs/stable/index.html