由于网上代码的画图功能是基于jupyter记事本,而我用的是pycham,这导致画图代码不兼容pycharm,所以删去部分代码,以便能更好的在pycharm上运行
完整代码:
python
import torch
from d2l import torch as d2l
"创建训练集&创建检测集合"
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
"创建模型w, b"
num_inputs = 784
num_outputs = 10
W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)
b = torch.zeros(num_outputs, requires_grad=True)
"softmax"
def softmax(X):
X_exp = torch.exp(X)
partition = X_exp.sum(1, keepdim=True)
return X_exp / partition # 这里应用了广播机制
"输出,即传入图片输出"
def net(X):
return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)
"交叉熵损失"
def cross_entropy(y_hat, y):
return - torch.log(y_hat[range(len(y_hat)), y])
"显示预测与估计相对应下标数量"
def accuracy(y_hat, y): #@save
"""计算预测正确的数量"""
if len(y_hat.shape) > 1 and y_hat.shape[1] > 1: # 确定长宽高都大于1
y_hat = y_hat.argmax(axis=1) # 取出每行中最大值
cmp = y_hat.type(y.dtype) == y
return float(cmp.type(y.dtype).sum()) # 返回对应下标数量
"利用优化后的模型计算精度"
def evaluate_accuracy(net, data_iter): #@save
if isinstance(net, torch.nn.Module):
net.eval() # 将模型设置为评估模式
metric = Accumulator(2) # 正确预测数、预测总数
with torch.no_grad():
for X, y in data_iter:
metric.add(accuracy(net(X), y), y.numel()) # 下标相同数量 / 总下标
return metric[0] / metric[1]
"加法器"
class Accumulator: #@save
def __init__(self, n):
self.data = [0.0] * n
def add(self, *args):
self.data = [a + float(b) for a, b in zip(self.data, args)]
def reset(self):
self.data = [0.0] * len(self.data)
def __getitem__(self, idx):
return self.data[idx]
"训练更新模型&返回训练损失与精度函数"
def train_epoch_ch3(net, train_iter, loss, updater): #@save
"""训练模型一个迭代周期(定义见第3章)"""
# 将模型设置为训练模式
if isinstance(net, torch.nn.Module):
net.train()
# 训练损失总和、训练准确度总和、样本数
metric = Accumulator(3)
for X, y in train_iter:
# 计算梯度并更新参数
y_hat = net(X)
l = loss(y_hat, y)
if isinstance(updater, torch.optim.Optimizer):
# 使用PyTorch内置的优化器和损失函数
updater.zero_grad()
l.mean().backward()
updater.step()
else:
# 使用定制的优化器和损失函数
l.sum().backward()
updater(X.shape[0])
metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())
# 返回训练损失和训练精度
return metric[0] / metric[2], metric[1] / metric[2]
lr = 0.1
"更新模型"
def updater(batch_size):
return d2l.sgd([W, b], lr, batch_size)
if __name__ == '__main__':
num_epochs = 10
cnt = 1
for i in range(num_epochs):
X, Y = train_epoch_ch3(net, train_iter, cross_entropy, updater)
print("训练次数: " + str(cnt))
cnt += 1
print("训练损失: {:.4f}".format(X))
print("训练精度: {:.4f}".format(Y))
print(".................................")
# print(W)
# print(b)
效果:
训练效果还是和网上一样的,就是缺了画图功能,将就着吧