精华内容
下载资源
问答
  • 问题2描述:resnet50迁移学习,最终训练上的准确率一直在攀升,但验证机上的准确率一直上不去,在一定程度上出现了过拟合现象,但加很多的BN、dropout、l1和l2正则化手段都不能有效的解决问题。 ...

    keras之resnet50迁移学习做分类

    问题1描述:迁移学习用resnet50做分类,验证集上的准确率一直是一个大问题,有时候稳定在一个低的准确率,我的一次是一直在75%上下波动。

    问题2描述:resnet50迁移学习,训练集上的准确率一直在攀升,但验证集上的准确率一直上不去,一定程度上出现了过拟合现象,但加很多的BN、dropout、l1和l2正则化手段都不能有效的解决问题。

    ***问题1答案:***这个问题网络设计没有问题的话,一般出现在训练的数据量上,数据量偏少就会出现验证集上准确率一直很低。

    问题2答案:

    2020/10/12更新

    根本原因可参考:https://github.com/keras-team/keras/pull/9965
    解决方案:在这里插入图片描述其实就是加一个参数:layers=tf.keras.layers

    下面的采坑可不看

    --------------------------------------------

    -----------------------------------------------

    先来看一下一般resnet50迁移学习的网络设计:

     base_model = ResNet50(weights='imagenet', include_top=False,
                                  input_shape=(image_size, image_size, 3), )
    x = base_model.output
    x = GlobalAveragePooling2D(name='average_pool')(x)
    x = Flatten(name='flatten')(x)
    

    这是一个典型的残差网络做迁移学习的套路,很多人都是这么做的,但真的有很高的准确率吗?反正我试了很多次,一直出现验证集上的准确率很低上不去的问题。不管怎么用防止过拟合的手段,效果都不是很好。后来研究BN层看了几篇相关的论文,发现包括resnet,inception等模型都包含了Batch Normalization层,如果使用pretrained参数进行finetune,这些BN层一般情况下使用了K.learning_phase的值作为is_training参数的默认值,因此导致训练的时候使用的一直是mini batch的平均值 ,由于trainable在finetune时候一般设置为false了导致整个layer 不会update,因此moving_mean\variance根本没有更新。导致你在test时用的moving_mean\variance全是imagenet数据集上的值。
    参考链接:https://github.com/keras-team/keras/pull/9965
    修正后的代码:

    K.set_learning_phase(0)
    base_model = ResNet50(weights='imagenet', include_top=False,
                                  input_shape=(image_size, image_size, 3), )
     K.set_learning_phase(1)
    x = base_model.output
    x = GlobalAveragePooling2D(name='average_pool')(x)
    x = Flatten(name='flatten')(x)
    x = Dense(2048, activation='relu', kernel_regularizer=regularizers.l2(0.0001), )(x)
    x = BatchNormalization()(x)
    x = Dense(1024, activation='relu', kernel_regularizer=regularizers.l2(0.0001))(x)
    x = BatchNormalization(name='bn_fc_01')(x)
    predictions = Dense(num_classes, activation='softmax')(x)
    model = Model(inputs=base_model.input, outputs=predictions)
    

    这样更正后可以使得准确率有一个良好的上升,但优化的不够彻底,再有一些小的技巧可以让你的验证集上的准确率有更好的提升。这是一个试验,没有理论支持,如果上述的方案不能满足你对准确率的要求,不妨试试下面这个方案:

    K.set_learning_phase(0)
    Inp = Input((224, 224, 3))
    base_model = ResNet50(weights='imagenet', include_top=False,
                                  input_shape=(image_size, image_size, 3), )
     K.set_learning_phase(1)
     x = base_model(Inp)
    x = GlobalAveragePooling2D(name='average_pool')(x)
    x = Flatten(name='flatten')(x)
    ...
    predictions = Dense(num_classes, activation='softmax')(x)
    model = Model(inputs=Inp, outputs=predictions)
    

    可看出区别了吗?下面代码将输入变更了,不用resnet的输出做输入,直接定义自己的输入,我有测试过,这样做确实对准确率有一定的提升。基本上resnet50迁移学习的坑就踩到这里。

    展开全文
  • 救救孩子吧,孩子的头都快秃了 ... 具体就是这样,一张图就能说明问题,不管我给了10000张图,还是给了2000张,不管我的损失函数和激活函数怎么变,始终是这个曲线(其实应该更加的平稳) 代码在下面(我用的是jupyter ...
  • 损失函数一直在下降,为什么识别率上不去。 1.最常见的原因:过拟合 过拟合值得单独开个章节。主要包括 1.数据量小,网络复杂 2.learning rate 比较高,又没有设置任何防止过拟合的机制 解决方法主要包括 1....

    损失函数一直在下降,为什么识别率上不去。

    ----------------2021-01-08更新-----------------------

    0.学习率设置太高,一个epoch直接收敛,所以损失不会下降

    比如学利率一开始设置为1,因为下降太快,那么很有可能在一个epoch旧完全收敛。所以看到的validation数值并不下降,第一个epoch就已经处于谷底了。所以如果使用的是系统默认的学习率,最好检查下默认值是什么。

     

    -------------------旧---------------------------------------

    1.最常见的原因:过拟合

    过拟合值得单独开个章节。主要包括

    1.数据量小,网络复杂

    2.learning rate 比较高,又没有设置任何防止过拟合的机制

    解决方法主要包括

    1.简化模型,利用现有深度学习手段增加数据(翻转,平移,随机裁剪,imgaug)

    2.利用 dropout层

    3.利用正则化

    2.你犯了错误:没有把数据规格化

    图片的话,img/255是肯定的

    3.你犯了错误:没有在分验证集之前打乱数据

    因为validation_split操作不会为你shuffle数据,所以如果你的数据前一半标签全是1 ,后一半全是0,validation=0.5。恭喜你,你压根也分不对,你的validation准确率会一直为0.因为你拿所有的正样本训练,却想判断负样本。

    4.你犯了错误,数据和标签没有对上

    有可能再读取自定义的数据库的时候出现问题,导致数据与标注不对应。比如第一张图片用第十张的标注

    5.你的训练数据太少,validation数据太多,类别也太多

    比如4000张训练,1000张validation,300类,这显然就是不合理的。

    遇到这种情况,建议:

        1.使用别的大的数据集预训练

        2.使用DATA augment

        3.可以考虑迁移学习

     

    6.最好使用预训练的权重

    大多数流行的backone比如resnet都有再imagenet数据集上与训练过,那么使用这种权重,比起随即重新训练,显然要可靠不少注意调整学习率。

    7.网络结构有问题

    可以通过使用现在流行的网络(resnet,unet等)替入你的代码,如果结果没有问题,你的结果有问题那么肯定就是你网络结构出问题了。那么可以通过逐层注释掉排查究竟哪里出了问题

    7.1 网络最后一层没有使用正确的激活函数

    比如多类的应该使用softmax

    8.relu后面是softmax

    有一些说法是relu由于对于很大的数值直接复制,所以会对softmax产生不好的影响,从而输出不好的结果。所以可以使用tanh代替relu。

    9.batch normalization需要batch size至少16张

    https://mp.csdn.net/postedit/89456400

    由于做dense prediction图片通常比较大。所以一个batch一般都只有1-2张图片,不建议使用 BN。

    因为BN一般是16张图片以上一起跑。所以吧,如果是BN,那么请用多GPU,16以上的batch size。s

    另外keras TF1.x可能会出问题,https://github.com/keras-team/keras/pull/9965

    10.你犯了错误,你可能设置了一些参数是不可训练的

    在训练语句之前,检查以下你的trainable参数,是否设置了一些参数是不可训练的。这还可能导致你的输出只能是一个值,比如永远预测为标注0,因为你只有一点点的参数,而这并不是一个模型(比如只有100个参数是可以训练的,太简单了,无法模拟)。

     

    11.附送一个调参论文

    Bag of Tricks for Image Classification with Convolutional Neural Networks

    https://arxiv.org/abs/1812.01187

    NLP 独有错误 

    最傻的错误,比如train和val使用了不一样的字典,那效果能好才怪了。。。。

    展开全文
  • 不过昨天那个对半划分数据集,一半作为训练集,一半作为验证集的划分方式效果实在是令人敢恭维。。。我是死了心这么分了。到时候毕设答辩的时候拿这个说简直就是丢死人了。 正文 我这次采用的是以前的那一拨...

    正文之前

    昨天好不容易心气爆发,肝了一会儿的毕业设计,也算是初步走上了正轨,很是期待后面完成之后我自己回首会是怎样一般场景了!不过昨天那个对半划分数据集,一半作为训练集,一半作为验证集的划分方式效果实在是令人不敢恭维。。。我是死了心这么分了。到时候毕设答辩的时候拿这个去说简直就是丢死人了。

    正文

    我这次采用的是以前的那一拨钢板的数据集,清洗数据后剩下六个属性,分类也分为六类。这就构成了这个1940条记录的数据集。但是因为数据的分类过于集中。很是让人烦恼!

    诸君请看,前面的这些异常分类都是0,也就是对应的故障列表的第一项:

    String[] Fault = new String[]{"Pastry","Z_Scratch","K_Scatch","Stains","Dirtiness","Bumps","Other_Faults"};
    复制代码

    mysql> select min(id) from steelplate where Fault=1;
    +---------+
    | min(id) |
    +---------+
    |     158 |
    +---------+
    1 row in set (0.01 sec)
    复制代码

    分类为1 的最小的记录编号都已经到了158了。所以我选择交叉获取数据的方式分配训练集和数据集。即第一条到训练集,第二条到验证集。这样下来尚且算是分配均匀了。

    不过各位看看最终的实验效果就知道。。我这个分配均匀到底有多坑了!

    准确率0.51。。。。堪堪过半!!简直无敌自容了好吗?!!!!所以今天我准备修改训练集和验证集 的比例,调成4:1左右的话会不会好一点呢?肯定会的好吗?这时候训练集有1552,测试集388。而且继续采用交叉办法,肯定能有较好的效果了!

    不过,我还没开始呢。。。所以先放0.51的代码。然后下面再来一篇放另外的吧!!

    //读取测试集和验证集的方法
       public Object[][] readTrainData() {
            int columnCount=0;
            try {
                mysql.Connect();
                Statement statement=mysql.getStatement();
                String GETCOLUMN="select max(id) from steelplate";
                String getDataQuery="";
                Object[][] DataTrain;
                ResultSet answer = statement.executeQuery(GETCOLUMN);
                if(answer.next())
                    columnCount  = answer.getInt(1);
                DataTrain = new Object[columnCount/2][7];
                for (int  i = 0;i<columnCount/2;++i) {
                    getDataQuery = getSelectQuery(Name,"steelplate",i*2);
                    ResultSet select_ok;
                    select_ok = statement.executeQuery(getDataQuery);
                    select_ok.next();
                    for (int j = 0; j<7;++j){
                        DataTrain[i][j]=select_ok.getObject((String) Name[j]);
                    }
                }
                statement.close();
                mysql.Dis_Connect();
                return DataTrain;
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new Object[1][1];
        }
    
        public Object[][] readTestData() {
            int columnCount=0;
            try {
                mysql.Connect();
                Statement statement=mysql.getStatement();
                String GETCOLUMN="select max(id) from steelplate";
                Object[][] DataTest;
                ResultSet answer = statement.executeQuery(GETCOLUMN);
                if(answer.next())
                    columnCount  = answer.getInt(1);
                DataTest = new Object[columnCount/2][7];
                for (int  i = 0 ;i<columnCount/2-1;++i) {
                    String getDataQuery = getSelectQuery(Name,"steelplate",i*2+1);
                    ResultSet select_ok;
                    select_ok = statement.executeQuery(getDataQuery);
                    select_ok.next();
                    for (int j = 0; j<7;++j){
                        DataTest[i][j]=select_ok.getObject((String) Name[j]);
                    }
                }
                statement.close();
                mysql.Dis_Connect();
                return DataTest;
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new Object[1][1];
        }
    复制代码

    下面是读取验证集并且计算正确率的函数

    else if(command.toLowerCase().equals("autotest")){
                if (TData.isEmpty()){
                    jl12.setText(Space+"Please Open the Test File to load the Data!");
                    return;
                }
                else {
                    for (int i=0;i<TData.size();++i) {
                        Object[] test = TData.get(i).split(" ");
                        String res="";
                        res=TestData.TestData(tree, Test_Names,test,res);
                        if (res.contains(":")){
                            String Fault = res.substring(res.indexOf(":")+1);
                            Fault = Fault.trim();
                            String Fa = FaultMap.get(Fault);
                            if(Fa.equals((String) test[test.length-1])){
                                RightCount++;
                            }
                            else {
                                FaultCount++;
                            }
                        }
                        else {
                            FaultCount++;
                        }
                    }
                    System.out.println(RightCount+" "+FaultCount);
                    jl12.setText(Space+"准确率: "+((float)RightCount/(float)(RightCount+FaultCount)));
                    RightCount = 0;
                    FaultCount = 0;
                }
            }
    复制代码

    另外还有一个故障编号Map

        public  Map<String,String> FaultMap = new HashMap<String,String>();
            FaultMap.put("Pastry","0");
            FaultMap.put("Z_Scratch","1");
            FaultMap.put("K_Scatch","2");
            FaultMap.put("Stains","3");
            FaultMap.put("Dirtiness","4");
            FaultMap.put("Bumps","5");
            FaultMap.put("Other_Faults","6");
    复制代码

    正文之后

    溜了溜了。。。我室友借我车去吃饭,结果半路上跟外卖小哥来了段相爱相杀,求问这种时候我室友还垫付了200+的医药费,万一外卖小哥纠缠报警的话会吃亏不?外卖小哥的车技一向是。。。生死时速的!

    展开全文
  • 本次实验中,我使用的是keras的vgg16模型,然后再添加了三层全连接层对花进行识别,50个epoch后在验证集中的准确率为87.63,不算很好,但有由于确实太耗费时间了,就太想重新调参然后训练了,就只能勉强接受了。...

    前言

    刚完成机器视觉的作业(利用预训练好的模型,对花的数据集进行识别),所以就记录一下。本次实验中,我使用的是keras的vgg16模型,然后再添加了三层全连接层对花进行识别,50个epoch后在验证集中的准确率为87.63,不算很好,但有由于确实太耗费时间了,就不太想去重新调参然后训练了,就只能勉强接受了。
    我的实验数据是直接在kaggle上下的,链接:Flowers Recognition

    VGG16

    VGG是Oxford的Visual Geometry Group的组提出的。该网络是在ILSVRC 2014上的相关工作,主要工作是证明了增加网络的深度能够在一定程度上影响网络最终的性能。VGG16共包含16个卷积层(Convolutional Layer),3个全连接层(Fully connected Layer),以及5个池化层(Pool layer),其中,卷积层和全连接层具有权重系数,因此也被称为权重层,总数目为13+3=16,这即是VGG16中16的来源。
    VGG16的突出特点是:
    1.卷积层均采用相同的卷积核参数。卷积层均表示为conv3-XXX,其中conv3说明该卷积层采用的卷积核的尺寸(kernel size)是3,即宽(width)和高(height)均为3,3*3是很小的卷积核尺寸,结合其它参数(步幅stride=1,填充方式padding=same),这样就能够使得每一个卷积层(张量)与前一层(张量)保持相同的宽和高。XXX代表卷积层的通道数。
    2.池化层均采用相同的池化核参数。池化层的参数均为2×。
    3.模型是由若干卷积层和池化层堆叠(stack)的方式构成,比较容易形成较深的网络结构(在2014年,16层已经被认为很深了)。
    VGG16网络结构:
    在这里插入图片描述

    实验源码及结果展示

    源码

    其实也很简单,就是直接在keras上调取VGG16模型就行了,不过模型比较大,可能需要下载一会。

    import os
    import cv2
    import random
    from tensorflow.python.keras.applications import VGG16, VGG19
    from tensorflow.python.keras import Sequential
    from tensorflow.python.keras import layers
    from tensorflow.python.keras.optimizers import SGD
    from tensorflow.python.keras.models import Model
    import matplotlib.pyplot as plt
    import numpy as np
    
    def get_data():
        data = []
        labels = []
        types = os.listdir('./flowers')
        for name in types:
            flowers = os.listdir('./flowers' + '/' + name)
            for flower in flowers:
                img = cv2.imread('./flowers' + '/' + name + '/' + flower)
                img = cv2.resize(img, (240, 320))
                data.append(img)
                labels.append(name)
        return data, labels
    if __name__ == '__main__':
        type = {"daisy": 0, "dandelion": 1, "rose": 2, "sunflower": 3, "tulip": 4}
        data, labels = get_data()
        # 打包数据并打乱
        upset = list(zip(data, labels))
        random.shuffle(upset)
        data[:], labels[:] = zip(*upset)
        train_data = np.array([data[i] for i in range(len(labels)) if i % 9 > 1])
        train_label = [labels[i] for i in range(len(labels)) if i % 9 > 1]
        test_data = np.array([data[i] for i in range(len(labels)) if i % 9 <= 1])
        test_label = [labels[i] for i in range(len(labels)) if i % 9 <= 1]
        train_labels = np.zeros((len(train_label), 5))
        test_labels = np.zeros((len(test_label), 5))
        for i in range(len(train_labels)):
            train_labels[i][type[train_label[i]]] = 1
        for i in range(len(test_labels)):
            test_labels[i][type[test_label[i]]] = 1
    
        sgd = SGD(lr=0.001, decay=1e-6, momentum=0.9, nesterov=True)
    
    
        model_vgg16 = VGG16(weights='imagenet', include_top=False, input_shape=(320, 240, 3))
        for layer in model_vgg16.layers:
            layer.trainable = False
        model = layers.Flatten(name='flatten')(model_vgg16.output)
        model = layers.Dense(64, activation='relu')(model)
        model = layers.BatchNormalization()(model)
        model = layers.Dropout(0.5)(model)
        model = layers.Dense(32, activation='relu')(model)
        model = layers.BatchNormalization()(model)
        model = layers.Dropout(0.5)(model)
        model = layers.Dense(5, activation='softmax')(model)
        model = Model(inputs=model_vgg16.input, outputs=model, name='vgg16')
    
    
        model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
        history = model.fit(train_data, train_labels, batch_size=256, epochs=50, validation_data=(test_data, test_labels))
        plt.plot(history.history['accuracy'], label='training acc')
        plt.plot(history.history['val_accuracy'], label='val acc')
        plt.title('model accuracy')
        plt.ylabel('accuracy')
        plt.xlabel('epoch')
        plt.show()
        plt.close()
        plt.plot(history.history['loss'], label='training loss')
        plt.plot(history.history['val_loss'], label='val loss')
        plt.title('model loss')
        plt.ylabel('loss')
        plt.xlabel('epoch')
        plt.show()
        plt.close()
    
    

    实验结果

    在经过50个epoch训练后,实验的训练精度达到了96.91,而验证精度为87.63.
    Epoch 50/50
    3361/3361 [==============================] - 46s 14ms/sample - loss: 0.1543 - accuracy: 0.9691 - val_loss: 0.3734 - val_accuracy: 0.8763
    从模型准确度和损失图可以看出,在经过20个epoch左右,验证集的准确度和损失变大就很小了,没太多了提升空间了,最后验证集精度也基本稳定在87-88了,验证损失停留在在0.37 -0.38。本来想多做几组实验对照一下,但由于需要的计算时间的资源太大就放弃了,目前的效果也就还行。
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 这也能解释为什么评论里到处都是问准确率的问题,拿着一个有问题的训练当然训练不好。 最后需要指明一点的是,这个代码所需要的GPU性能还是挺高的,尤其是显存要求。我自己的使用数据(...
  • 训练过程--对loss和acc的分析、处理

    万次阅读 多人点赞 2018-12-06 14:10:33
      其实你这个问题就是个伪命题,如果我们刻意的在训练集上拟合模型,使其准确率达到很高的高度,或者说尽量在验证集合表现的好,都是相悖的。   因为我们能为了某一特定数据来刻意拟合,因为模型预测...
  • 训练过程–对loss和acc的分析、处理。...其实你这个问题就是个伪命题,如果我们刻意的在训练集上拟合模型,使其准确率达到很高的高度,或者说尽量在验证集合表现的好,都是相悖的。   因为我们...
  • 【lightgbm 使用经验总结教训】

    万次阅读 2018-06-13 13:49:14
    -大数据挑战赛有半个月了,从5月30日开始到现在基本一直在构造特征,但是当我构造的特征到后期的时候,发现加特征之后,明明验证集上准确率提高了,但是线上的结果一直提上去,我怀疑的是特征的问题,但是今天6...
  • fastText优点是可以快速的在cpu进行训练,但是准确率不高。 fastText将输入的文本特征通过一层全连接层映射到向量空间,然后将词向量平均处理一下,做预测。 keras模型搭建如图: 三,fastText的实现 1.pip...
  • Deep text matching 1、前言 Github 上面有很多文本匹配项目,本项目工作主要借鉴了 和 ,模型的...由于训练集、验证集、测试集中的正负样本比例都是1:1,因此我使用了准确率这一评价指标来衡量了这些模型的性能,结果
  • 将传统的卷积结构改造成两层卷积结构的网络,在基本影响准确率的前提下大大减少计算时间,更适合移动端和嵌入式视觉应用 ImageNet-2012验证集 70.99%/89.68% MobileNetV2 MobileNet结构的微调,直接在 thinner ...
  • 数据量:训练集(53,360),验证集(10,000),测试集(10,000) 例子: {"label": "102", "label_des": "news_entertainment", "sentence": "江疏影甜甜圈自拍,迷之角度竟这么好看,美吸引一切事物"} 每一条数据有三...
  • 在测试集上准确率达到了96.04%,且各类的precision, recall和f1-score都超过了0.9。 从混淆矩阵也可以看出分类效果非常优秀。 RNN循环神经网络 配置项 RNN可配置的参数如下所示,在rnn_model.py中。 class ...
  • RFID数据流近似去重

    2015-10-06 23:50:24
    如果每个商品都有一个标签,那么一个大型的零售商每天产生的数据将会超过1TB,并且,RFID数据是以流的形式产生的,也就意味着冗余数据在一个有限的内存中要立即进行去重处理,我们很难设计出一个精确的冗余办法...
  • 测试准确率比ver.1有明显提高,由于我们更关注负类准度,再查看其他评价指标。 召回率 confuse_matrix(y_test, pred_y_test) >>>[[2527 455] [ 618 1960]] Precision = 0.85, Recall = 0.80 F1 = 0.82 查...
  • matlab神经网络30个案例分析

    千次下载 热门讨论 2011-06-01 20:06:07
    本章要解决的问题就是仅仅利用训练找到分类的最佳参数,不但能够高准确率的预测训练而且要合理的预测测试,使得测试的分类准确率也维持在一个较高水平,即使得得到的SVM分类器的学习能力和推广能力保持一个...
  • 自己尝试基于Baseline的模型进行优化或尝试其他模型以提升结果准确率 Task06:拓展阅读:语音识别基础知识介绍(1天) 了解语音识别的基础背景知识 2. Docker教程 开源内容:...
  • 现有的主流NAS算法通过子网络在验证集上的预测性能来进行模型搜索,但是在参数共享机制下,验证集上的预测性能和模型真实性能存在较大的差异。我们首次打破了这种基于预测性能进行模型评估的范式,从模型收敛速度的...

空空如也

空空如也

1 2 3
收藏数 41
精华内容 16
关键字:

验证集准确率上不去