• 总是遇到奇怪问题一


    1.遇到报错ValueError: optimizer got an empty parameter list

    在pycharm上也是报相同的错误

    完整代码:

     1 import torch
     2 import torch.nn as nn
     3 from torch.optim import SGD
     4 import torch.utils.data as Data
     5 from sklearn.datasets import load_boston
     6 from sklearn.preprocessing import StandardScaler
     7 import pandas as pd
     8 import numpy as np
     9 import matplotlib.pyplot as plt
    10 ##读取数据
    11 boston_X,boston_y= load_boston(return_X_y=True)
    12 print("boston_X.shape:",boston_X.shape)
    13 plt.figure()
    14 plt.hist(boston_y,bins=20)
    15 plt.show()
    16 ##数据标准化处理
    17 ss = StandardScaler(with_mean=True,with_std=True)
    18 boston_Xs= ss.fit_transform(boston_X)
    19 ##将数据预处理为可以使用pytorch进行批量训练的形式
    20 ##训练X转化为张量
    21 train_xt= torch.from_numpy(boston_Xs.astype(np.float32))
    22 ##训练集y转化为张量
    23 train_yt = torch.from_numpy(boston_y.astype(np.float32))
    24 ##将训练集转化为张量后,使用TensorDataset将X和Y整理到一起
    25 train_data = Data.TensorDataset(train_xt,train_yt)
    26 ##定义一个数据加载器,将训练数据集进行批量处理
    27 train_loader = Data.DataLoader(
    28     dataset = train_data,   ##使用的数据集
    29     batch_size = 128,       ##批量处理样本的大小
    30     shuffle = True,         ##每次迭代前打乱数据
    31     num_workers = 1,        ##使用两个进程
    32 )
    33 ##使用继承Module的方式定义全连接神经网络
    34 class MLPmodel(nn.Module):
    35     def _init_(self):
    36         super(MLPmodel,self)._init_()
    37         ##定义第一个隐藏层
    38         self.hidden1 = nn.Linear(
    39             in_features = 13,   ##第一个隐藏层的输入,数据的特征数
    40             out_feature = 10,   ##第一个隐藏层的输出,神经元的数量
    41             bias = True,
    42         )
    43         self.activel = nn.ReLU()
    44         ##定义第二个隐藏层
    45         self.hidden2 = nn.Linear(10,10)
    46         self.active2 = nn.ReLU()
    47         ##定义预测回归层
    48         self.regression = nn.Linear(10,1)
    49     ##定义网络的前向传播路径
    50     def forward(self, x):
    51         x=self.hidden1(x)
    52         x=self.active1(x)
    53         x=self.hidden2(x)
    54         x=self.active2(x)
    55         output=self.regression(x)
    56         ##输出为output
    57         return output
    58 ##输出网络结构
    59 mlp1 = MLPmodel()
    60 print(mlp1)
    61 ##对回归模型mlp1进行训练并输出损失函数的变化情况,定义优化器和损失函数
    62 optimizer = SGD(mlp1.parameters(),lr=0.001)
    63 loss_func = nn.MSELoss()    ##最小均方根误差
    64 train_loss_all = [ ]         ##输出每个批次训练的损失函数
    65 ##进行训练,并输出每次迭代的损失函数
    66 for epoch in range(30):
    67     ##对训练数据的加载器进行迭代计算
    68     for step,(b_x,b_y) in enumerate(train_loader):
    69         output = mlp1(b_x).flatten()     ##MLP在训练batch上的输出
    70         train_loss = loss_func(output,b_y)  ##均方根误差
    71         optimizer.zero_grad()             ##每个迭代步的梯度初始化为0
    72         train_loss.backward()             ##损失的向后传播,计算梯度
    73         optimizer.step()                  ##使用梯度进行优化
    74         train_loss_all.append(train_loss.item())
    75 plt.figure()
    76 plt.plot(train_loss_all,"r-")
    77 plt.title("Train loss per iteration")
    78 plt.show()
    View Code

     解决:

    在写_init_的时候左右边上一个下划线  _   ,因此报错,但实际需要使用的代码当中并非是这个函数,而是__init__  ,即左右两边是两个下划线
    此错误为低级错误,缺花费了很多时间。


    2.遇到错误
    在运行以下代码时总是出错

    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
    AttributeError: 'NoneType' object has no attribute 'shape'

     原因可能是:当使用cv2的时候,1.图片不存在(路径不存在, 路径包含中文无法识别) 2.读取的图片内容和默认读取时参数匹配不匹配。(默认读取的是3通道的彩色图)例如读取到的图片是灰度图,就会返回None。

    在我这个运行的代码当中,其中是第一种,其中路径包含了中文,因此报错,只需将中文切换为中文即可。

    ## 导入本章所需要的模块
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import requests
    import cv2
    
    import torch
    from torch import nn
    import torch.nn.functional as F
    from torchvision import models
    from torchvision import transforms
    from PIL import Image
    
    ## 导入预训练好的VGG16网络
    vgg16 = models.vgg16(pretrained=True)
    print(vgg16)
    
    ## 读取一张图片,并对其进行可视化
    im = Image.open("data/chap6/大象.jpg")
    imarray = np.asarray(im) / 255.0
    plt.figure()
    plt.imshow(imarray)
    plt.show()
    
    imarray.shape
    
    ## 对一张图像处理为vgg16网络可以处理的形式
    data_transforms = transforms.Compose([
        transforms.Resize((224,224)),# 重置图像分辨率
        transforms.ToTensor(),# 转化为张量并归一化至[0-1]
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
    input_im = data_transforms(im).unsqueeze(0)
    print("input_im.shape:",input_im.shape)
    
    ## 使用钩子获取分类层的2个特征
    ## 定义一个辅助函数,来获取指定层名称的特征
    activation = {} ## 保存不同层的输出
    def get_activation(name):
        def hook(model, input, output):
            activation[name] = output.detach()
        return hook
    
    ## 获取中间的卷积后的图像特征
    vgg16.eval()
    ##  第四层,经过第一次最大值池化
    vgg16.features[4].register_forward_hook(get_activation("maxpool1"))
    _ = vgg16(input_im)
    maxpool1 = activation["maxpool1"]
    print("获取特征的尺寸为:",maxpool1.shape)
    
    ## 对中间层进行可视化,可视化64个特征映射
    plt.figure(figsize=(11,6))
    for ii in range(maxpool1.shape[1]):
        ## 可视化每张手写体
        plt.subplot(6,11,ii+1)
        plt.imshow(maxpool1.data.numpy()[0,ii,:,:],cmap="gray")
        plt.axis("off")
    plt.subplots_adjust(wspace=0.1, hspace=0.1)
    plt.show()
    
    ## 获取更深层次的卷积后的图像特征
    vgg16.eval()
    vgg16.features[21].register_forward_hook(get_activation("layer21_conv"))
    _ = vgg16(input_im)
    layer21_conv = activation["layer21_conv"]
    print("获取特征的尺寸为:",layer21_conv.shape)
    
    ## 对中间层进行可视化,只可视化前72个特征映射
    plt.figure(figsize=(12,6))
    for ii in range(72):
        ## 可视化每张手写体
        plt.subplot(6,12,ii+1)
        plt.imshow(layer21_conv.data.numpy()[0,ii,:,:],cmap="gray")
        plt.axis("off")
    plt.subplots_adjust(wspace=0.1, hspace=0.1)
    plt.show()
    
    ## 获取vgg模型训练时对应的1000类的类别标签
    LABELS_URL = "https://s3.amazonaws.com/outcome-blog/imagenet/labels.json"
    # 从网页链接中获取类别标签
    response = requests.get(LABELS_URL)
    labels = {int(key): value for key, value in response.json().items()}
    
    ## 使用VGG16网络预测图像的种类
    vgg16.eval()
    im_pre = vgg16(input_im)
    ## 计算预测top-5的可能性
    softmax = nn.Softmax(dim=1)
    im_pre_prob = softmax(im_pre)
    prob,prelab = torch.topk(im_pre_prob,5)
    prob = prob.data.numpy().flatten()
    prelab = prelab.numpy().flatten()
    for ii,lab in enumerate(prelab):
       print("index: ", lab ," label: ",labels[lab]," ||",prob[ii])
    
    # African elephant 非洲大象
    # tusker 长牙动物
    # Indian elephant 印度象,亚洲象属maximus
    # water buffalo 水牛
    # Weimaraner 威马
    ## 定义一个萌购输出最后的卷机层输出和梯度的新的网络
    class MyVgg16(nn.Module):
        def __init__(self):
            super(MyVgg16, self).__init__()
    
            # 使用预训练好的VGG16模型
            self.vgg = models.vgg16(pretrained=True)
            # 切分vgg6模型,便于获取卷积层的输出
            self.features_conv = self.vgg.features[:30]
            # 使用原始的最大值池化层
            self.max_pool = self.vgg.features[30]
            self.avgpool = self.vgg.avgpool
            # 使用vgg16的分类层
            self.classifier = self.vgg.classifier
            # 生成梯度占位符
            self.gradients = None
    
        # 获取地图的钩子函数
        def activations_hook(self, grad):
            self.gradients = grad
    
        def forward(self, x):
            x = self.features_conv(x)
            # 注册钩子
            h = x.register_hook(self.activations_hook)
            # 对卷积后的输出使用最大值池化
            x = self.max_pool(x)
            x = self.avgpool(x)
            x = x.view((1, -1))
            x = self.classifier(x)
            return x
    
        # 获取梯度的方法
        def get_activations_gradient(self):
            return self.gradients
    
        # 获取卷机层输出的方法
        def get_activations(self, x):
            return self.features_conv(x)
    
    
    # 初始化网络
    vggcam = MyVgg16()
    # 设置网络的模式
    vggcam.eval()
    ## 计算网络对图像的预测值
    im_pre = vggcam(input_im)
    ## 计算预测top-5的可能性
    softmax = nn.Softmax(dim=1)
    im_pre_prob = softmax(im_pre)
    prob, prelab = torch.topk(im_pre_prob, 5)
    prob = prob.data.numpy().flatten()
    prelab = prelab.numpy().flatten()
    for ii, lab in enumerate(prelab):
        print("index: ", lab, " label: ", labels[lab], " ||", prob[ii])
    
    ## 这里预测结果和前面的一样,可能性最大的是第101个编号
    
    # 获取相对于模型参数的输出梯度
    im_pre[:, prelab[0]].backward()
    # 获取模型的梯度
    gradients = vggcam.get_activations_gradient()
    # 计算梯度相应通道的均值
    mean_gradients = torch.mean(gradients, dim=[0, 2, 3])
    # 获取图像在相应卷积层输出的卷积特征
    activations = vggcam.get_activations(input_im).detach()
    # m每个通道乘以相应的梯度均值
    for i in range(len(mean_gradients)):
        activations[:, i, :, :] *= mean_gradients[i]
    # 计算所有通道的均值输出得到热力图
    heatmap = torch.mean(activations, dim=1).squeeze()
    # 使用relu函数作用于热力图
    heatmap = F.relu(heatmap)
    # 对热力图进行标准化
    heatmap /= torch.max(heatmap)
    heatmap = heatmap.numpy()
    # 可视化热力图
    plt.matshow(heatmap)
    
    ## 将Grad-CAM热力图融合到原始图像上
    img = cv2.imread("data/chap6/aliphone.jpg")
    #im = Image.open("data/chap6/大象.jpg")
    print("大象img的尺寸为:",img.shape[1], img.shape[0])
    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
    heatmap = np.uint8(255 * heatmap)
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
    Grad_cam_img = heatmap * 0.4 + img
    Grad_cam_img = Grad_cam_img / Grad_cam_img.max()
    ## 可视化图像
    b,g,r = cv2.split(Grad_cam_img)
    Grad_cam_img = cv2.merge([r,g,b])
    plt.figure()
    plt.imshow(Grad_cam_img)
    plt.show()
    
    ## 可视化老虎图像的Grad-cam
    im = Image.open("data/chap6/老虎.jpg")
    input_im = data_transforms(im).unsqueeze(0)
    
    # 初始化网络
    vggcam = MyVgg16()
    # 设置网络的模式
    vggcam.eval()
    ## 计算网络对图像的预测值
    im_pre = vggcam(input_im)
    ## 计算预测top-5的可能性
    softmax = nn.Softmax(dim=1)
    im_pre_prob = softmax(im_pre)
    prob, prelab = torch.topk(im_pre_prob, 5)
    prob = prob.data.numpy().flatten()
    prelab = prelab.numpy().flatten()
    for ii, lab in enumerate(prelab):
        print("index: ", lab, " label: ", labels[lab], " ||", prob[ii])
    
    # 获取相对于模型参数的输出梯度
    im_pre[:, prelab[0]].backward()
    # 获取模型的梯度
    gradients = vggcam.get_activations_gradient()
    # 计算梯度相应通道的均值
    mean_gradients = torch.mean(gradients, dim=[0, 2, 3])
    # 获取图像在相应卷积层输出的卷积特征
    activations = vggcam.get_activations(input_im).detach()
    # m每个通道乘以相应的梯度均值
    for i in range(len(mean_gradients)):
        activations[:, i, :, :] *= mean_gradients[i]
    # 计算所有通道的均值输出得到热力图
    heatmap = torch.mean(activations, dim=1).squeeze()
    # 使用relu函数作用于热力图
    heatmap = F.relu(heatmap)
    # 对热力图进行标准化
    heatmap /= torch.max(heatmap)
    heatmap = heatmap.numpy()
    # 可视化热力图
    plt.matshow(heatmap)
    
    ## 将Grad-CAM热力图融合到原始图像上
    img = cv2.imread("data/chap6/老虎.jpg")
    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
    heatmap = np.uint8(255 * heatmap)
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
    Grad_cam_img = heatmap * 0.5 + img
    Grad_cam_img = Grad_cam_img / Grad_cam_img.max()
    ## 可视化图像
    b, g, r = cv2.split(Grad_cam_img)
    Grad_cam_img = cv2.merge([r, g, b])
    plt.figure()
    plt.imshow(Grad_cam_img)
    plt.show()
    View Code
  • 相关阅读:
    ASP.NET 4.0 与 Entity Framework 4第三篇使用Entity Framework调用存储过程
    雕虫无小技 JavaScript初学者的10个迷你技巧
    IE6下button随着文字的增多两边的内容边框也会增加的bug
    bigint ,int ,smallint ,tinyint 数据类型
    分享7个不错的jQuery游戏( 转)
    IE CSS Bug及解决方案参考手册
    利用CSS样式打印
    SQL 2005 弹出不允许对系统目录进行即席更新解决方法
    VS2010快捷键
    SQL2K,DTC错误:"该伙伴事务管理器已经禁止了它对远程/网络事务的支持"的解决办法
  • 原文地址:https://www.cnblogs.com/2020zxc/p/13438148.html
Copyright © 2020-2023  润新知