"""
------------------------------前馈神经网络------------------------
"""
import torch
from torch import nn, optim
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
#举例说明:比如数据集样本数是60000,一次训练32个样本,要迭代(或循环)1875次才能训练完所有样本。训练完一次就是1个num_epoches
batch_size = 32#每批数据量的大小。
learning_rate = 1e-2
num_epoches = 1#1个epoch指用全部样本训练一次
# 下载训练集 MNIST 手写数字训练集
train_dataset = datasets.MNIST(
root='F:/PycharmProjects/pytorch-beginner-master/02-Logistic Regression/data', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = datasets.MNIST(
root='F:/PycharmProjects/pytorch-beginner-master/02-Logistic Regression/data', train=False, transform=transforms.ToTensor())
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
print("train_len: ", len(train_loader))
"""前馈(feedforward)也可以称为前向,从信号流向来理解就是输入信号进入网络后,信号流动是单向的,即信号从前一层流向后一层,
一直到输出层,其中任意两层之间的连接并没有反馈(feedback),亦即信号没有从后一层又返回到前一层。如果从输入输出关系来理解,
则为当输入信号进入后,输入层之后的每一个层都将前一个层的输出作为输入。如下图所示的四层网络,这个图也可以称为有向无环路图。
反之,当前馈神经网络中层与层之间的信号有反向流动,或者自输入时,我们则称这种网络为循环神经网络,循环神经网络在自然语言处理
方面发挥着极大的作用。"""
# 定义简单的前馈神经网络
class Neuralnetwork(nn.Module):
def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
super(Neuralnetwork, self).__init__()
# self.layer1 = nn.Sequential(
# nn.Linear(in_dim, n_hidden_1), #输入存
# nn.ReLU(True)) #//隐藏网络:elu的功能是将输入的feature的tensor所有的元素中如果小于零的就取零。
# 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),#输出存
# nn.ReLU(True))
self.layer = nn.Sequential(
nn.Linear(in_features=in_dim, out_features=n_hidden_1),#输入是[batch_size=32,28*28] 输出是[batch_size=32,300] weight是[28*28,300]
nn.ReLU(True),
nn.Linear(n_hidden_1, n_hidden_2),#输入是[batch_size=32,300] 输出是[batch_size=32,100] weight是[300,100]
nn.ReLU(True),
nn.Linear(n_hidden_2, out_dim)#输入是[batch_size=32,100] 输出是[batch_size=32,10] weight是[100,10]
)
def forward(self, x):
x = self.layer(x)
# x = self.layer2(x)
# x = self.layer3(x)
return x
model = Neuralnetwork(28 * 28, 300, 100, 10)
if torch.cuda.is_available():
model = model.cuda()
# 3.定义损失函数和criterionoptimizer(优化函数)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
for epoch in range(num_epoches):
print('epoch {}'.format(epoch + 1))
print('*' * 10)
running_loss = 0.0
running_acc = 0.0
for i, data in enumerate(train_loader, 1):
img, label = 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)
# 向前传播
out = model(img)#img=[32,28*28]
loss = criterion(out, label)
running_loss += loss.item() * label.size(0)
_, pred = torch.max(out, 1)
num_correct = (pred == label).sum()
running_acc += num_correct.item()
# 向后传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
if i % 300 == 0:
print(img.size())
print('[{}/{}] Loss: {:.6f}, Acc: {:.6f}'.format(
epoch + 1, num_epoches, running_loss / (batch_size * i),
running_acc / (batch_size * i)))
print('Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format(
epoch + 1, running_loss / (len(train_dataset)), running_acc / (len(
train_dataset))))
model.eval()
eval_loss = 0.
eval_acc = 0.
for data in test_loader:
img, label = data
img = img.view(img.size(0), -1)
if torch.cuda.is_available():
img = Variable(img, volatile=True).cuda()
label = Variable(label, volatile=True).cuda()
else:
img = Variable(img, volatile=True)
label = Variable(label, volatile=True)
out = model(img)
loss = criterion(out, label)
eval_loss += loss.item() * label.size(0)
_, pred = torch.max(out, 1)
num_correct = (pred == label).sum()
eval_acc += num_correct.item()
print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len(
test_dataset)), eval_acc / (len(test_dataset))))
print()
# 保存模型
torch.save(model.state_dict(), 'F:/PycharmProjects/pytorch-beginner-master/03-Neural Network/neural_network.pth')