深度学习打卡1

"""
使用Mnist数据集来测试上节使用的cross entropy
"""
import  torch
import  torch.nn as nn
import  torch.nn.functional as F
import  torch.optim as optim
from    torchvision import datasets, transforms

#1、设置网络超参数
batch_size=200
learning_rate=0.01
epochs=10

#2、从网上下载MNIST的数据集
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('mnist_data', train=True, download=False,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=batch_size, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('mnist_data', train=False, download=False,
                   transform=transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize((0.1307,), (0.3081,))
                    ])),
    batch_size=batch_size, shuffle=True)


#3、这里是网络--为了便于理解优化过程,所以这样写
w1, b1 = torch.randn(200, 784, requires_grad=True), torch.zeros(200, requires_grad=True)
w2, b2 = torch.randn(200, 200, requires_grad=True), torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10,  200, requires_grad=True), torch.zeros(10,  requires_grad=True)

#这里使用了kaiming (He initialization)---凯明初始化方法,专门针对relu激活函数的初始化方法---加了这个凯明初始化以后结果出现了很好地变换
torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3)

#4、网络的搭建
def forward(x):
    x = x@w1.t() + b1
    x = F.relu(x)             #使用relu函数,不会出现梯度弥散的情况---loss长时间得不到更新,loss最后出现一个常值---梯度信息接近于0
    x = x@w2.t() + b2
    x = F.relu(x)
    x = x@w3.t() + b3
    x = F.relu(x)              #最后的输出层,relu激活函数是可以不要的
    return x
"""
影响training的因素有:
1、learning rate过大
2、gradient vanish---梯度弥散(参数梯度为0,导致loss保持为常数,loss长时间得不到更新)
3、初始化问题----参数初始化问题
"""

#我们使用的是SGD优化器
optimizer = optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate)
criteon = nn.CrossEntropyLoss()     #计算分类误差--LOSS

#训练模型---train
for epoch in range(epochs):           #一个epoch是指train完整个数据集
                                                                   #batch_idx=[0-299]
    for batch_idx, (data, target) in enumerate(train_loader):      # data[b,1,28,28]--->[b,784]; target[b]  b--->batch_size
        data = data.view(-1, 28*28)   #这个view的用法还不是很熟悉,这个是再不更改数据量大小的情况在,改变tensor的shape
        logits = forward(data)         #这里是网络的输出
        loss = criteon(logits, target)  #调用cross—entorpy计算输出值和真实值之间的loss

        optimizer.zero_grad()           #然后是一系列的优化梯度更新,优化参数
        loss.backward()
        optimizer.step()

        if batch_idx % 100 == 0:        #每100个bachsize打印输出的结果,看看loss的情况
              print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
        epoch, batch_idx * len(data), len(train_loader.dataset),
               100. * batch_idx/ len(train_loader), loss.item()))
        """
        len(data)---指的是一个batch_size;
        len(train_loader.dataset)----指的是train_loader这个数据集中总共有多少张图片(数据)
        len(train_loader)---- len(train_loader.dataset)/len(data)---就是这个train_loader要加载多少次batch       
        """
#测试网络---test----每训练完一个epoch检测一下测试结果---因为每一个epoch已经优化了batch次参数,得到的参数信息还是OK的
    test_loss = 0
    correct = 0
    for data, target in test_loader:
        data = data.view(-1, 28 * 28)                   #[200,1,28,28]
        logits = forward(data)                          #logits的shape=[200,10]--200是batchsize,10是最后输出结果的10分类
        test_loss += criteon(logits, target).item()     #每次将test_loss进行累加   #target=[200,1]---每个类只有一个正确结果

        pred = logits.data.max(1)[1]
        #这里losgits.data是一个二维数组;其dim=1;max()---返回的是每行的最大值和最大值对应的索引
        #max(1)----是指每行取最大值;max(1)[1]---取每行最大值对应的索引号
        correct += pred.eq(target.data).sum()           #预测值和目标值相等个数进行求和--在for中,将这个test_loader中相等的个数都求出来

    test_loss /= len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值