Skip to content

  • 体验新版
    • 正在加载...
  • 登录
  • PaddlePaddle
  • Paddle
  • Issue
  • #23501

P
Paddle
  • 项目概览

PaddlePaddle / Paddle
大约 2 年 前同步成功

通知 2325
Star 20933
Fork 5424
  • 代码
    • 文件
    • 提交
    • 分支
    • Tags
    • 贡献者
    • 分支图
    • Diff
  • Issue 1423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
  • Wiki 0
    • Wiki
  • 分析
    • 仓库
    • DevOps
  • 项目成员
  • Pages
P
Paddle
  • 项目概览
    • 项目概览
    • 详情
    • 发布
  • 仓库
    • 仓库
    • 文件
    • 提交
    • 分支
    • 标签
    • 贡献者
    • 分支图
    • 比较
  • Issue 1,423
    • Issue 1,423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
    • 合并请求 543
  • Pages
  • 分析
    • 分析
    • 仓库分析
    • DevOps
  • Wiki 0
    • Wiki
  • 成员
    • 成员
  • 收起侧边栏
  • 动态
  • 分支图
  • 创建新Issue
  • 提交
  • Issue看板
已关闭
开放中
Opened 4月 06, 2020 by saxon_zh@saxon_zhGuest

复现改造AlexNet,无法收敛,acc一直是0.5左右,检查了很多方面还是找不出问题

Created by: hubu-wangpei

如题,根据paddle的教程和图像隐写分析的模型,改造了AlexNet模型。但是在训练的时候,最后的全连接层输出的预测值都是比较小的值,在0附近(下面有图),经过sigmoid函数后的值都在0.5左右。导致acc一直在0.5上下,loss在0.69左右,试过很多网上的方法,都不行。训练集里正反例各一半,训练时,随机读取。下面是具体代码

import cv2
import random
import numpy as np

# 对读入的图像数据进行预处理
def transform_img(img):

    #数据集是PGM格式的灰度图像,但是cv2读入的时候也是(256,256,3)即三通道
    # 读入的图像数据格式是[H, W, C]
    # 使用转置操作将其变成[C, H, W]
    img = img[np.newaxis, :]
    img = img.astype('float32')

    #img.reshape(1,256,256)
    # 将数据范围调整到[-1.0, 1.0]之间
    img = img / 255.
    img = img * 2.0 - 1.0
    return img

# 定义训练集数据读取器
def data_loader(datadir, batch_size=10, mode = 'train'):
    # 将datadir目录下的文件列出来,每条文件都要读入
    filenames = os.listdir(datadir)
    def reader():
        if mode == 'train':
            # 训练时随机打乱数据顺序
            random.shuffle(filenames)
        batch_imgs = []
        batch_labels = []
        #print(filenames[:10])
        for name in filenames:
            filepath = os.path.join(datadir, name)
            img = cv2.imread(filepath,0)
            img = transform_img(img)
            if name[0] == 'c' :
                # c开头的文件名表示载体图片,cover
                # 属于负样本,标签为0
                label = 0
            elif name[0] == 's':
                # S开头的是载密图像,属于正样本,标签为1
                label = 1
            else:
                print(name)
                raise('Not excepted file name')
            # 每读取一个样本的数据,就将其放入数据列表中
            batch_imgs.append(img)
            batch_labels.append(label)
            if len(batch_imgs) == batch_size:
                # 当数据列表的长度等于batch_size的时候,
                # 把这些数据当作一个mini-batch,并作为数据生成器的一个输出
                imgs_array = np.array(batch_imgs).astype('float32')
                labels_array = np.array(batch_labels).astype('float32').reshape(-1, 1)
                yield imgs_array, labels_array
                batch_imgs = []
                batch_labels = []

        if len(batch_imgs) > 0:
            # 剩余样本数目不足一个batch_size的数据,一起打包成一个mini-batch
            imgs_array = np.array(batch_imgs).astype('float32')
            labels_array = np.array(batch_labels).astype('float32').reshape(-1, 1)
            yield imgs_array, labels_array

    return reader
    
##########################################################

import os
import random
import paddle
import paddle.fluid as fluid
import numpy as np

DATADIR =  '/home/aistudio/data/data26700/train'
DATADIR2 = '/home/aistudio/data/data26700/valid'


# 定义训练过程
def train(model):
    with fluid.dygraph.guard():
        print('start training ... ')
        model.train()
        epoch_num = 5
        # 定义优化器
        opt = fluid.optimizer.AdadeltaOptimizer(learning_rate=0.0003, epsilon=1.0e-6, rho=0.95, parameter_list=model.parameters())
        #opt = fluid.optimizer.Momentum(learning_rate=0.001, momentum=0.4, parameter_list=model.parameters())
        #opt=fluid.optimizer.SGD(learning_rate=0.001,parameter_list=model.parameters())
        # 定义数据读取器,训练数据读取器和验证数据读取器
        train_loader = data_loader(DATADIR, batch_size=20, mode='train')
        valid_loader = data_loader(DATADIR2,batch_size=20, mode='valid' )
        for epoch in range(epoch_num):
            accuracies = []
            for batch_id, data in enumerate(train_loader()):
                x_data, y_data = data
                #print(x_data,y_data)
                img = fluid.dygraph.to_variable(x_data)
                label = fluid.dygraph.to_variable(y_data)
                # 运行模型前向计算,得到预测值
                logits = model(img)
                
                # 进行loss计算
                loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
                avg_loss = fluid.layers.mean(loss)

                pred = fluid.layers.sigmoid(logits)
                
                # 计算预测概率小于0.5的类别
                pred2 = pred * (-1.0) + 1.0
                # 得到两个类别的预测概率,并沿第一个维度级联
                pred = fluid.layers.concat([pred2, pred], axis=1)
                acc = fluid.layers.accuracy(pred, fluid.layers.cast(label, dtype='int64'))
                accuracies.append(acc.numpy())
                if batch_id % 100 == 0:
                    print(logits)
                    print("epoch: {}, batch_id: {}, acc is :{}  loss is: {}".format(epoch, batch_id,np.mean(accuracies), avg_loss.numpy()))
                # 反向传播,更新权重,清除梯度
                avg_loss.backward()
                opt.minimize(avg_loss)
                model.clear_gradients()

            model.eval()
            accuracies = []
            losses = []
            for batch_id, data in enumerate(valid_loader()):
                x_data, y_data = data
                img = fluid.dygraph.to_variable(x_data)
                label = fluid.dygraph.to_variable(y_data)
                # 运行模型前向计算,得到预测值
                logits = model(img)
                # 二分类,sigmoid计算后的结果以0.5为阈值分两个类别
                # 计算sigmoid后的预测概率,进行loss计算
                pred = fluid.layers.sigmoid(logits)
                loss = fluid.layers.sigmoid_cross_entropy_with_logits(logits, label)
                # 计算预测概率小于0.5的类别
                pred2 = pred * (-1.0) + 1.0
                # 得到两个类别的预测概率,并沿第一个维度级联
                pred = fluid.layers.concat([pred2, pred], axis=1)
                acc = fluid.layers.accuracy(pred, fluid.layers.cast(label, dtype='int64'))
                accuracies.append(acc.numpy())
                losses.append(loss.numpy())
            print("[validation] accuracy/loss: {}/{}".format(np.mean(accuracies), np.mean(losses)))
            model.train()

        # save params of model
        fluid.save_dygraph(model.state_dict(), 'mnist')
        # save optimizer state
        fluid.save_dygraph(opt.state_dict(), 'mnist')

#####################################################
import numpy as np
import paddle
import paddle.fluid as fluid
from paddle.fluid.layer_helper import LayerHelper
from paddle.fluid.dygraph.nn import Conv2D, Pool2D, BatchNorm, Linear
from paddle.fluid.dygraph.base import to_variable
from paddle.fluid.initializer import NumpyArrayInitializer

# 定义 AlexNet 网络结构
class AlexNet(fluid.dygraph.Layer):
    def __init__(self, name_scope, num_classes=1):
        super(AlexNet, self).__init__(name_scope)
        name_scope = self.full_name()
        # AlexNet与LeNet一样也会同时使用卷积和池化层提取图像特征
        # 与LeNet不同的是激活函数换成了‘relu’

        SRM_kernel=np.load("/home/aistudio/work/SRM_Kernels.npy") 
        SRM_kernel=np.transpose(SRM_kernel,[3,2,0,1])
        # self.conv0 = Conv2D(num_channels=1, num_filters=30, filter_size=[5, 5],    
        #     param_attr=fluid.ParamAttr(
        #       initializer=NumpyArrayInitializer(value=SRM_kernel),trainable=False))
        self.conv0 = Conv2D(num_channels=1, num_filters=30, filter_size=5, stride=1, padding=0)

        self.conv1 = Conv2D(num_channels=30, num_filters=30, filter_size=3, stride=1, padding=0, act='relu')
        self.conv2 = Conv2D(num_channels=30, num_filters=30, filter_size=3, stride=1, padding=0, act='relu')

        self.conv3 = Conv2D(num_channels=30, num_filters=30, filter_size=3, stride=1, padding=0, act='relu')
        self.pool3 = Pool2D(pool_size=2, pool_stride=2, pool_type='avg')

        self.conv4 = Conv2D(num_channels=30, num_filters=32, filter_size=5, stride=1, padding=0, act='relu')
        self.pool4 = Pool2D(pool_size=3, pool_stride=2, pool_type='avg')

        self.conv5 = Conv2D(num_channels=32, num_filters=32, filter_size=5, stride=1, padding=0, act='relu')
        self.pool5 = Pool2D(pool_size=3, pool_stride=2, pool_type='avg')

        self.conv6 = Conv2D(num_channels=32, num_filters=32, filter_size=5, stride=1, padding=0, act='relu')
        self.pool6 = Pool2D(pool_size=3, pool_stride=2, pool_type='avg')
        self.bn=BatchNorm(32, act='relu')
        self.conv7 = Conv2D(num_channels=32, num_filters=16, filter_size=3, stride=1, padding=0, act='relu')
        self.conv8 = Conv2D(num_channels=16, num_filters=16, filter_size=3, stride=3, padding=0, act='relu')

        #self.fc1 = fluid.layers.fc(input_dim=144, output_dim=1)

        import math
        stdv = 1.0 / math.sqrt(2048 * 1.0)
    
        # 创建全连接层,输出大小为类别数目
        self.fc1 = Linear(input_dim=144, output_dim=1)
        
    def forward(self, x):
        x=self.conv0(x)
        #print("conv1-- kernel_size:{}, padding:{}, stride:{}".format(self.conv1.weight.shape, self.conv1._padding, self.conv1._stride))
  
        x=fluid.layers.clip(x=x, min=-3.0, max=3.0)
        x = self.conv1(x)
       # print(x.shape)
        x = self.conv2(x)
        x = self.conv3(x)
        x = self.pool3(x)
        x = self.conv4(x)
        x = self.pool4(x)
        x = self.conv5(x)
        x = self.pool5(x)
        x = self.conv6(x)
        x = self.pool6(x)
        #x =self.bn(x)
        x = self.conv7(x)
        x = self.conv8(x)
        x = fluid.layers.reshape(x, [x.shape[0], -1])
        x=self.fc1(x)
        return x

use_cuda = True
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()

with fluid.dygraph.guard(place):
    model = AlexNet("AlexNet")

train(model)

每一层卷积层又加了bachnorm,但还是不收敛,下面是训练的时候的数据

图片

指派人
分配到
无
里程碑
无
分配里程碑
工时统计
无
截止日期
无
标识: paddlepaddle/Paddle#23501
渝ICP备2023009037号

京公网安备11010502055752号

网络110报警服务 Powered by GitLab CE v13.7
开源知识
Git 入门 Pro Git 电子书 在线学 Git
Markdown 基础入门 IT 技术知识开源图谱
帮助
使用手册 反馈建议 博客
《GitCode 隐私声明》 《GitCode 服务条款》 关于GitCode
Powered by GitLab CE v13.7