import pandas as pd
import torch
import torch.nn as nn
import numpy as np
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader
from torch import optim
from torchvision import datasets, transforms
from torch.utils.data.dataloader import default_collate
from torchvision.datasets import ImageFolder
from torchvision.datasets.folder import default_loader
x = torch.randn(3, 4, requires_grad = True)
print(x)
b = torch.randn(3, 4, requires_grad = True)
t = x + b
y = t.sum()
print(y)
y.backward()
print(b.grad)
print(x.requires_grad, b.requires_grad, t.requires_grad )
x_values = [i for i in range(11)]
x_train = np.array(x_values, dtype = np.float32)
x_train = x_train.reshape(-1, 1)
print(x_train.shape)
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)
print(y_train.shape)
class LinearRegressionModel(nn.Module) :
def __init__ (self, input_dim, output_dim) :
super(LinearRegressionModel, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward (self, x) :
out = self.linear(x)
return out
input_dim = 1
output_dim = 1
model = LinearRegressionModel(input_dim, output_dim)
print(model)
epochs = 1000
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)
criterion = nn.MSELoss()
for epoch in range(epochs) :
epoch += 1
inputs = torch.from_numpy(x_train)
labels = torch.from_numpy(y_train)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print('epoch {}, loss {}'.format(epoch, loss.item()))
predicted = model(torch.from_numpy(x_train).requires_grad_()).data.numpy()
print(predicted)
torch.save(model.state_dict(), 'model.pkl')
model.load_state_dict(torch.load('model.pkl'))
'''
PyTorch 的 torch.nn 包提供了很多与实现神经网络中的具体功能相关的类,
这些类涵盖了深度神经网络模型在搭建和参数优化过程中的常用内容。
troch.nn.Sequential 是 torch.nn 中的一种序列容器,通过在容器中嵌套各种实现神经网络中具体功能相关的
类,来完成对神经网络模型的搭建,最主要的是,参数会按照我们定义好的序列自动喘息下去。
模块的加入一般由两种方式,一种是在代码中直接嵌套,另一种是以 orderdict 有序字典
的方式进行传入
第一种
hidden_layer = 100
input_data = 1000
outout_data = 10
models = torch.nn.Sequential (
torch.nn.Linear(input_data, hidden_layer),
torch.nn.ReLU(),
torch.nn.Linear(hidden_layer, output_data)
)
第二种
使用 orderdict 有序字典进行传入来搭建的模型
from collections import OrderedDict
modles = torch.nn.Sequential(OrderDict([
("Linel", torch.nn.Linear(input_data, hidden_layer)),
("ReLU", torch.nn.ReLU()),
("Line2", torch.nn.Linear(hidden_layer, output_data))
]))
torch.nn.Linear 用于定义模型的线性层,即完成不同层之间的线性转换,
参数为3, 输入特征束,输出特征束,是否使用偏置
torch.nn.ReLU 属于非线性激活函数,在定义时默认不传入参数
可以选择的有 PReLU LeakyReLU Tanh Sigmoid Softmax
torch.nn.MSFLoss 使用均方误差函数对损失值进行计算
torch.nn.L1Loss 使用平均绝对无法函数对损失值进行计算
torch.nn.CrossEntropyLoss 计算交叉熵
更新参数
for param in models.paramters() :
param.data -= param.grad.data * learning_rate
在 PyTorch 的 troch.optim 包中提供了非常多的可实现参数自动优化的类
比如 SGD AdaGrad RMSProp Adam
optimizer = torch.optim.Adam(models.parameters()m lr = learning_rate)
optimzer.zero_grad 来完成对模型参数梯度的归零
optimzer.step 主要功能是使用计算得到的梯度值对各个节点的参数进行梯度更新
'''
'''
Variable 和 Tensor 本质上没有区别,不过 Variable 会被放入一个计算图中,然后进行
前向传播、反向传播、自动求导
torch.autograd.Variable
Variable(a)
'''
'''
torch.utils.data.Dataset 是代表这一数据的抽象类,可以定义数据类来继承和重写这个抽象类
只需要定义 __len__ 和 __getitem__ 两个函数
'''
class myDataset(Dataset) :
def __init__(self, csv_file, txt_file, root_dir, other_file):
self.csv_data = pd.read_csv(csv_file)
with open(txt_file, 'r') as f:
data_list = f.readline()
self.txt_data = data_list
self.root_dir = root_dir
def __len__(self):
return len(self.csv_data)
def __getitem__(self, idx):
data = (self.csv_data[idx], self.txt_data[idx])
return data
'''
PyTorch 里边编写的神经网络所有的层结构和损失函数都来自 torch.nn
所有模型都继承子 nn.Module
'''
'''
使用 gpu 训练模型
if torch.cuda.is_available():
model = LinearRegression().cuda()
else:
model - LinearRegression()
'''
def make_features(x):
x = x.unsqueeze(1)
return torch.cat([x ** i for i in range(1, 4)], 1)
W_target = torch.FloatTensor([0.5, 3, 2.4]).unsqueeze(1)
b_target = torch.FloatTensor([0.9])
print('w target : {}, \nb_target : {}'.format(W_target, b_target))
def f(x):
return x.mm(W_target) + b_target[0]
def get_batch(batch_size = 32):
random = torch.randn(batch_size)
x = make_features(random)
y = f(x)
return Variable(x), Variable(y)
print('\nget batch : {}'.format(get_batch()))
class poly_model(nn.Module):
def __init__(self):
super(poly_model, self).__init__()
self.poly = nn.Linear(3, 1)
def forward(self, x):
out = self.poly(x)
return out
model = poly_model()
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr = 1e-3)
epoch = 0
while True:
batch_x, batch_y = get_batch()
output = model(batch_x)
loss = criterion(output, batch_y)
print_loss = loss.item()
optimizer.zero_grad()
loss.backward()
optimizer.step()
epoch += 1
if print_loss < 1e-3:
break
class simpleNet(nn.Module):
def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
super(simpleNet, self).__init__()
self.layer1 = nn.Linear(in_dim, n_hidden_1)
self.layer2 = nn.Linear(n_hidden_1, n_hidden_2)
self.layer3 = nn.Linear(n_hidden_2, out_dim)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
class Activation_Net(nn.Module):
def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
super(Activation_Net, self).__init__()
self.layer1 = nn.Sequential(
nn.Linear(in_dim, n_hidden_1),
nn.ReLU(True)
)
self.layer2 = nn.Sequential(
nn.Linear(n_hidden_1, n_hidden_2),
nn.ReLU(True)
)
self.layer3 = nn.Sequential(
nn.Linear(n_hidden_2, out_dim)
)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
class Batch_Net(nn.Module):
def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
super(Batch_Net, self).__init__()
self.layer1 = nn.Sequential(
nn.Linear(in_dim, n_hidden_1),
nn.BatchNorm1d(n_hidden_1),
nn.ReLU(True)
)
self.layer2 = nn.Sequential(
nn.Linear(n_hidden_1, n_hidden_2),
nn.BatchNorm1d(n_hidden_2),
nn.ReLU(True)
)
self.layer3 = nn.Sequential(
nn.Linear(n_hidden_2, out_dim)
)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
batch_size = 64
learning_rate = 1e-3
num_epoches = 20
data_tf = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize([0.5], [0.5])]
)
train_dataset = datasets.MNIST(
root = './data',
train = True,
transform = data_tf,
download = True
)
test_dataset = datasets.MNIST(
root = './data',
train = False,
transform = data_tf
)
train_loader = DataLoader(train_dataset, batch_size = batch_size, shuffle = True)
test_loader = DataLoader(test_dataset, batch_size = batch_size, shuffle = False)
model = Batch_Net(28 * 28, 3000, 1000, 10)
if torch.cuda.is_available():
model = model.cuda()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr = learning_rate)
for epoch in range(num_epoches) :
epoch += 1
for train_data in train_loader:
img, label = train_data
img = img.view(img.size(0), -1)
if torch.cuda.is_available():
img = Variable(img).cuda()
label = Variable(label).cuda()
else:
img = Variable(img)
label = Variable(label)
optimizer.zero_grad()
outputs = model(img)
loss = criterion(outputs, label)
loss.backward()
optimizer.step()
print('epoch {}, loss {}'.format(epoch, loss.item()))