精华内容
下载资源
问答
  • 继续前面关于深度学习CNN经典模型的整理,之前介绍了CNN网络Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning(点击查看)的网络结构。本文讲一下最新由UC Berkeley和Stanford研究人员一起完成的SqueezeNet[1]...

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld。
    技术交流QQ群:433250724,欢迎对算法、技术感兴趣的同学加入。


    继续前面关于深度学习CNN经典模型的整理,之前介绍了CNN网络Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning(点击查看)的网络结构。

    本文讲一下最新由UC Berkeley和Stanford研究人员一起完成的SqueezeNet[1]网络结构和设计思想。SqueezeNet设计目标不是为了得到最佳的CNN识别精度,而是希望简化网络复杂度,同时达到public网络的识别精度。所以SqueezeNet主要是为了降低CNN模型参数数量而设计的。OK,下面直奔主题了。

    设计原则

    (1)替换3x3的卷积kernel为1x1的卷积kernel

    卷积模板的选择,从12年的AlexNet模型一路发展到2015年底Deep Residual Learning模型,基本上卷积大小都选择在3x3了,因为其有效性,以及设计简洁性。本文替换3x3的卷积kernel为1x1的卷积kernel可以让参数缩小9X。但是为了不影响识别精度,并不是全部替换,而是一部分用3x3,一部分用1x1。具体可以看后面的模块结构图。

    (2)减少输入3x3卷积的input feature map数量
    如果是conv1-conv2这样的直连,那么实际上是没有办法减少conv2的input feature map数量的。所以作者巧妙地把原本一层conv分解为两层,并且封装为一个Fire Module。

    (3)减少pooling
    这个观点在很多其他工作中都已经有体现了,比如GoogleNet以及Deep Residual Learning。

    Fire Module

    Fire Module是本文的核心构件,思想非常简单,就是将原来简单的一层conv层变成两层:squeeze层+expand层,各自带上Relu激活层。在squeeze层里面全是1x1的卷积kernel,数量记为S11;在expand层里面有1x1和3x3的卷积kernel,数量分别记为E11和E33,要求S11 < input map number即满足上面的设计原则(2)。expand层之后将1x1和3x3的卷积output feature maps在channel维度拼接起来。

    这里写图片描述

    总体网络架构

    直接上图说(左边的狗狗很忧伤啊):
    这里写图片描述

    看图就很明朗了,总共有9层fire module,中间穿插一些max pooling,最后是global avg pooling代替了fc层(参数大大减少)。在开始和最后还有两层最简单的单层conv层,保证输入输出大小可掌握。

    下图是更详细的说明:非常清楚,就不再啰嗦了。
    这里写图片描述

    实验结果

    主要在imagenet数据上比较了alexnet,可以看到准确率差不多的情况下,squeezeNet模型参数数量显著降低了(下表倒数第三行),参数减少50X;如果再加上deep compression技术,压缩比可以达到461X!还是不错的结果。不过有一点,用deep compression[2]是有解压的代价的,所以计算上会增加一些开销。

    这里写图片描述

    思考

    SqueezeNet之前我就在研究如果降低网络规模,SqueezeNet印证了小得多的网络也可以到达很好的CNN识别精度。相信以后会出现更多小网络,做到state-of-the-art的精度。好,本篇就介绍到这里,希望对大家有启发,有的话请支持一下我博客哈!~谢谢!

    参考资料

    [1] SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size,2016
    [2] Deep compression: Compressing DNNs with pruning, trained quantization and huffman coding, 2015

    展开全文
  • 继续前面关于深度学习CNN经典模型的整理,之前介绍了CNN网络Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning(点击查看)的网络结构。 本文讲一下最新由UC Berkeley和Stanford研究人员一起完成的S

    http://blog.csdn.net/xbinworld/article/details/50897870


    继续前面关于深度学习CNN经典模型的整理,之前介绍了CNN网络Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning(点击查看)的网络结构。

    本文讲一下最新由UC Berkeley和Stanford研究人员一起完成的SqueezeNet[1]网络结构和设计思想。SqueezeNet设计目标不是为了得到最佳的CNN识别精度,而是希望简化网络复杂度,同时达到public网络的识别精度。所以SqueezeNet主要是为了降低CNN模型参数数量而设计的。OK,下面直奔主题了。

    设计原则

    (1)替换3x3的卷积kernel为1x1的卷积kernel

    卷积模板的选择,从12年的AlexNet模型一路发展到2015年底Deep Residual Learning模型,基本上卷积大小都选择在3x3了,因为其有效性,以及设计简洁性。本文替换3x3的卷积kernel为1x1的卷积kernel可以让参数缩小9X。但是为了不影响识别精度,并不是全部替换,而是一部分用3x3,一部分用1x1。具体可以看后面的模块结构图。

    (2)减少输入3x3卷积的input feature map数量 
    如果是conv1-conv2这样的直连,那么实际上是没有办法减少conv2的input feature map数量的。所以作者巧妙地把原本一层conv分解为两层,并且封装为一个Fire Module。

    (3)减少pooling 
    这个观点在很多其他工作中都已经有体现了,比如GoogleNet以及Deep Residual Learning。

    Fire Module

    Fire Module是本文的核心构件,思想非常简单,就是将原来简单的一层conv层变成两层:squeeze层+expand层,各自带上Relu激活层。在squeeze层里面全是1x1的卷积kernel,数量记为S11;在expand层里面有1x1和3x3的卷积kernel,数量分别记为E11和E33,要求S11 < (E11+E33)即满足上面的设计原则(2)。expand层之后将1x1和3x3的卷积output feature maps在channel维度拼接起来。

    这里写图片描述

    总体网络架构

    直接上图说(左边的狗狗很忧伤啊): 
    这里写图片描述

    看图就很明朗了,总共有9层fire module,中间穿插一些max pooling,最后是global avg pooling代替了fc层(参数大大减少)。在开始和最后还有两层最简单的单层conv层,保证输入输出大小可掌握。

    下图是更详细的说明:非常清楚,就不再啰嗦了。 
    这里写图片描述

    实验结果

    主要在imagenet数据上比较了alexnet,可以看到准确率差不多的情况下,squeezeNet模型参数数量显著降低了(下表倒数第三行),参数减少50X;如果再加上deep compression技术,压缩比可以达到461X!还是不错的结果。不过有一点,用deep compression[2]是有解压的代价的,所以计算上会增加一些开销。

    这里写图片描述

    思考

    SqueezeNet之前我就在研究如果降低网络规模,SqueezeNet印证了小得多的网络也可以到达很好的CNN识别精度。相信以后会出现更多小网络,做到state-of-the-art的精度。好,本篇就介绍到这里,希望对大家有启发,有的话请支持一下我博客哈!~谢谢!

    参考资料

    [1] SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size,2016 
    [2] Deep compression: Compressing DNNs with pruning, trained quantization and huffman coding, 2015


    https://github.com/songhan/SqueezeNet-Deep-Compression


    展开全文
  • 文章目录前言适用于多时间步预测的CNN模型1 单变量多步预测 CNN 模型1.1 业务需求1.2 1D CNN 模型1.3 完整代码 前言 与其他机器学习算法不同,卷积神经网络能够从序列数据中自动学习特征,支持多变量数据,并可直接...
  •  文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类。总共有以下系列:  word2vec预训练词向量  textCNN 模型  charCNN 模型  Bi-...

    1 大纲概述

      文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类。总共有以下系列:

      word2vec预训练词向量

      textCNN 模型

      charCNN 模型

      Bi-LSTM 模型

      Bi-LSTM + Attention 模型

      RCNN 模型

      Adversarial LSTM 模型

      Transformer 模型

      ELMo 预训练模型

      BERT 预训练模型

      所有代码均在textClassifier仓库中。

     

    2 数据集

      数据集为IMDB 电影影评,总共有三个数据文件,在/data/rawData目录下,包括unlabeledTrainData.tsv,labeledTrainData.tsv,testData.tsv。在进行文本分类时需要有标签的数据(labeledTrainData),数据预处理如文本分类实战(一)—— word2vec预训练词向量中相似,唯一的不同是需要保留标点符号,否则模型难以收敛。预处理后的文件为/data/preprocess/labeledCharTrain.csv。

     

    3 charCNN 模型结构

      在charCNN论文Character-level Convolutional Networks for Text Classification中提出了6层卷积层 + 3层全连接层的结构,具体结构如下图:

      

      针对不同大小的数据集提出了两种结构参数:

      1)卷积层

        

      2)全连接层

        

     

    4 配置参数

    import os
    import time
    import datetime
    import csv
    import json
    from math import sqrt
    import warnings
    
    import numpy as np
    import pandas as pd
    import tensorflow as tf
    from sklearn.metrics import roc_auc_score, accuracy_score, precision_score, recall_score
    warnings.filterwarnings("ignore")
    # 参数配置
    
    class TrainingConfig(object):
        epoches = 10
        evaluateEvery = 100
        checkpointEvery = 100
        learningRate = 0.001
        
    
    class ModelConfig(object):
        
        # 该列表中子列表的三个元素分别是卷积核的数量,卷积核的高度,池化的尺寸
        convLayers = [[256, 7, 4],
                      [256, 7, 4],
                      [256, 3, 4]]
    #                   [256, 3, None],
    #                   [256, 3, None],
    #                   [256, 3, 3]]
        fcLayers = [512]
        dropoutKeepProb = 0.5
        
        epsilon = 1e-3  # BN层中防止分母为0而加入的极小值
        decay = 0.999  # BN层中用来计算滑动平均的值
        
        
    class Config(object):
       # 我们使用论文中提出的69个字符来表征输入数据 alphabet
    = "abcdefghijklmnopqrstuvwxyz0123456789-,;.!?:'\"/\\|_@#$%^&*~`+-=<>()[]{}" # alphabet = "abcdefghijklmnopqrstuvwxyz0123456789" sequenceLength = 1014 # 字符表示的序列长度 batchSize = 128 rate = 0.8 # 训练集的比例 dataSource = "../data/preProcess/labeledCharTrain.csv" training = TrainingConfig() model = ModelConfig() config = Config()

     

    5 训练数据生成

      1) 加载数据,将所有的句子分割成字符表示

      2) 构建字符-索引映射表,并保存成json的数据格式,方便在inference阶段加载使用

      3)将字符转换成one-hot的嵌入形式,作为模型中embedding层的初始化值。

      4) 将数据集分割成训练集和验证集

    # 数据预处理的类,生成训练集和测试集
    
    class Dataset(object):
        def __init__(self, config):
            self._dataSource = config.dataSource
            
            self._sequenceLength = config.sequenceLength
            self._rate = config.rate
            
            self.trainReviews = []
            self.trainLabels = []
            
            self.evalReviews = []
            self.evalLabels = []
            
            self._alphabet = config.alphabet
            self.charEmbedding =None
            
            self._charToIndex = {}
            self._indexToChar = {}
            
        def _readData(self, filePath):
            """
            从csv文件中读取数据集
            """
            
            df = pd.read_csv(filePath)
            labels = df["sentiment"].tolist()
            review = df["review"].tolist()
            reviews = [[char for char in line if char != " "] for line in review]
            
            return reviews, labels
    
        def _reviewProcess(self, review, sequenceLength, charToIndex):
            """
            将数据集中的每条评论用index表示
            wordToIndex中“pad”对应的index为0
            """
            
            reviewVec = np.zeros((sequenceLength))
            sequenceLen = sequenceLength
            
            # 判断当前的序列是否小于定义的固定序列长度
            if len(review) < sequenceLength:
                sequenceLen = len(review)
                
            for i in range(sequenceLen):
                if review[i] in charToIndex:
                    reviewVec[i] = charToIndex[review[i]]
                else:
                    reviewVec[i] = charToIndex["UNK"]
    
            return reviewVec
    
        def _genTrainEvalData(self, x, y, rate):
            """
            生成训练集和验证集
            """
            
            reviews = []
            labels = []
            
            # 遍历所有的文本,将文本中的词转换成index表示
            
            for i in range(len(x)):
                reviewVec = self._reviewProcess(x[i], self._sequenceLength, self._charToIndex)
                reviews.append(reviewVec)
                
                labels.append([y[i]])
                
            trainIndex = int(len(x) * rate)
            
            trainReviews = np.asarray(reviews[:trainIndex], dtype="int64")
            trainLabels = np.array(labels[:trainIndex], dtype="float32")
            
            evalReviews = np.asarray(reviews[trainIndex:], dtype="int64")
            evalLabels = np.array(labels[trainIndex:], dtype="float32")
    
            return trainReviews, trainLabels, evalReviews, evalLabels
            
        def _genVocabulary(self, reviews):
            """
            生成字符向量和字符-索引映射字典
            """
            
            chars = [char for char in self._alphabet]
            
            vocab, charEmbedding = self._getCharEmbedding(chars)
            self.charEmbedding = charEmbedding
            
            self._charToIndex = dict(zip(vocab, list(range(len(vocab)))))
            self._indexToChar = dict(zip(list(range(len(vocab))), vocab))
            
            # 将词汇-索引映射表保存为json数据,之后做inference时直接加载来处理数据
            with open("../data/charJson/charToIndex.json", "w", encoding="utf-8") as f:
                json.dump(self._charToIndex, f)
            
            with open("../data/charJson/indexToChar.json", "w", encoding="utf-8") as f:
                json.dump(self._indexToChar, f)
                
        def _getCharEmbedding(self, chars):
            """
            按照one的形式将字符映射成向量
            """
            
            alphabet = ["UNK"] + [char for char in self._alphabet]
            vocab = ["pad"] + alphabet
            charEmbedding = []
            charEmbedding.append(np.zeros(len(alphabet), dtype="float32"))
            
            for i, alpha in enumerate(alphabet):
                onehot = np.zeros(len(alphabet), dtype="float32")
                
                # 生成每个字符对应的向量
                onehot[i] = 1
                
                # 生成字符嵌入的向量矩阵
                charEmbedding.append(onehot)
                    
            return vocab, np.array(charEmbedding)
                
        def dataGen(self):
            """
            初始化训练集和验证集
            """
            
            # 初始化数据集
            reviews, labels = self._readData(self._dataSource)
            
            # 初始化词汇-索引映射表和词向量矩阵
            self._genVocabulary(reviews)
            
            # 初始化训练集和测试集
            trainReviews, trainLabels, evalReviews, evalLabels = self._genTrainEvalData(reviews, labels, self._rate)
            self.trainReviews = trainReviews
            self.trainLabels = trainLabels
            
            self.evalReviews = evalReviews
            self.evalLabels = evalLabels
            
            
    data = Dataset(config)
    data.dataGen()

     

     6 生成batch数据集

    # 输出batch数据集
    
    def nextBatch(x, y, batchSize):
            """
            生成batch数据集,用生成器的方式输出
            """
        
            perm = np.arange(len(x))
            np.random.shuffle(perm)
            x = x[perm]
            y = y[perm]
            
            numBatches = len(x) // batchSize
    
            for i in range(numBatches):
                start = i * batchSize
                end = start + batchSize
                batchX = np.array(x[start: end], dtype="int64")
                batchY = np.array(y[start: end], dtype="float32")
                
                yield batchX, batchY

     

    7 charCNN模型

      在charCNN 模型中我们引入了BN层,但是效果并不明显,甚至存在一些收敛问题,待之后去探讨。

    # 定义char-CNN分类器
    
    class CharCNN(object):
        """
        char-CNN用于文本分类
        """
        def __init__(self, config, charEmbedding):
            # placeholders for input, output and dropuot
            self.inputX = tf.placeholder(tf.int32, [None, config.sequenceLength], name="inputX")
            self.inputY = tf.placeholder(tf.float32, [None, 1], name="inputY")
            self.dropoutKeepProb = tf.placeholder(tf.float32, name="dropoutKeepProb")
            self.isTraining = tf.placeholder(tf.bool, name="isTraining")
            
            self.epsilon = config.model.epsilon
            self.decay = config.model.decay
            
            # 字符嵌入
            with tf.name_scope("embedding"):
                
                # 利用one-hot的字符向量作为初始化词嵌入矩阵
                self.W = tf.Variable(tf.cast(charEmbedding, dtype=tf.float32, name="charEmbedding") ,name="W")
                # 获得字符嵌入
                self.embededChars = tf.nn.embedding_lookup(self.W, self.inputX)
                # 添加一个通道维度
                self.embededCharsExpand = tf.expand_dims(self.embededChars, -1)
    
            for i, cl in enumerate(config.model.convLayers):
                print("开始第" + str(i + 1) + "卷积层的处理")
                # 利用命名空间name_scope来实现变量名复用
                with tf.name_scope("convLayer-%s"%(i+1)):
                    # 获取字符的向量长度
                    filterWidth = self.embededCharsExpand.get_shape()[2].value
                    
                    # filterShape = [height, width, in_channels, out_channels]
                    filterShape = [cl[1], filterWidth, 1, cl[0]]
    
                    stdv = 1 / sqrt(cl[0] * cl[1])
                    
                    # 初始化w和b的值
                    wConv = tf.Variable(tf.random_uniform(filterShape, minval=-stdv, maxval=stdv),
                                         dtype='float32', name='w')
                    bConv = tf.Variable(tf.random_uniform(shape=[cl[0]], minval=-stdv, maxval=stdv), name='b')
                    
    #                 w_conv = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.05), name="w")
    #                 b_conv = tf.Variable(tf.constant(0.1, shape=[cl[0]]), name="b")
                    # 构建卷积层,可以直接将卷积核的初始化方法传入(w_conv)
                    conv = tf.nn.conv2d(self.embededCharsExpand, wConv, strides=[1, 1, 1, 1], padding="VALID", name="conv")
                    # 加上偏差
                    hConv = tf.nn.bias_add(conv, bConv)
                    # 可以直接加上relu函数,因为tf.nn.conv2d事实上是做了一个卷积运算,然后在这个运算结果上加上偏差,再导入到relu函数中
                    hConv = tf.nn.relu(hConv)
                    
    #                 with tf.name_scope("batchNormalization"):
    #                     hConvBN = self._batchNorm(hConv)
                    
                    if cl[-1] is not None:
                        ksizeShape = [1, cl[2], 1, 1]
                        hPool = tf.nn.max_pool(hConv, ksize=ksizeShape, strides=ksizeShape, padding="VALID", name="pool")
                    else:
                        hPool = hConv
                        
                    print(hPool.shape)
        
                    # 对维度进行转换,转换成卷积层的输入维度
                    self.embededCharsExpand = tf.transpose(hPool, [0, 1, 3, 2], name="transpose")
            print(self.embededCharsExpand)
            with tf.name_scope("reshape"):
                fcDim = self.embededCharsExpand.get_shape()[1].value * self.embededCharsExpand.get_shape()[2].value
                self.inputReshape = tf.reshape(self.embededCharsExpand, [-1, fcDim])
            
            weights = [fcDim] + config.model.fcLayers
            
            for i, fl in enumerate(config.model.fcLayers):
                with tf.name_scope("fcLayer-%s"%(i+1)):
                    print("开始第" + str(i + 1) + "全连接层的处理")
                    stdv = 1 / sqrt(weights[i])
                    
                    # 定义全连接层的初始化方法,均匀分布初始化w和b的值
                    wFc = tf.Variable(tf.random_uniform([weights[i], fl], minval=-stdv, maxval=stdv), dtype="float32", name="w")
                    bFc = tf.Variable(tf.random_uniform(shape=[fl], minval=-stdv, maxval=stdv), dtype="float32", name="b")
                    
    #                 w_fc = tf.Variable(tf.truncated_normal([weights[i], fl], stddev=0.05), name="W")
    #                 b_fc = tf.Variable(tf.constant(0.1, shape=[fl]), name="b")
                    
                    self.fcInput = tf.nn.relu(tf.matmul(self.inputReshape, wFc) + bFc)
                    
                    with tf.name_scope("dropOut"):
                        self.fcInputDrop = tf.nn.dropout(self.fcInput, self.dropoutKeepProb)
                        
                self.inputReshape = self.fcInputDrop
                
            with tf.name_scope("outputLayer"):
                stdv = 1 / sqrt(weights[-1])
                # 定义隐层到输出层的权重系数和偏差的初始化方法
    #             w_out = tf.Variable(tf.truncated_normal([fc_layers[-1], num_classes], stddev=0.1), name="W")
    #             b_out = tf.Variable(tf.constant(0.1, shape=[num_classes]), name="b")
                
                wOut = tf.Variable(tf.random_uniform([config.model.fcLayers[-1], 1], minval=-stdv, maxval=stdv), dtype="float32", name="w")
                bOut = tf.Variable(tf.random_uniform(shape=[1], minval=-stdv, maxval=stdv), name="b")
                # tf.nn.xw_plus_b就是x和w的乘积加上b
                self.predictions = tf.nn.xw_plus_b(self.inputReshape, wOut, bOut, name="predictions")
                # 进行二元分类
                self.binaryPreds = tf.cast(tf.greater_equal(self.predictions, 0.0), tf.float32, name="binaryPreds")
                
                
            with tf.name_scope("loss"):
                # 定义损失函数,对预测值进行softmax,再求交叉熵。
                
                losses = tf.nn.sigmoid_cross_entropy_with_logits(logits=self.predictions, labels=self.inputY)
                self.loss = tf.reduce_mean(losses)
        
        def _batchNorm(self, x):
            # BN层代码实现
            gamma = tf.Variable(tf.ones([x.get_shape()[3].value]))
            beta = tf.Variable(tf.zeros([x.get_shape()[3].value]))
    
            self.popMean = tf.Variable(tf.zeros([x.get_shape()[3].value]), trainable=False, name="popMean")
            self.popVariance = tf.Variable(tf.ones([x.get_shape()[3].value]), trainable=False, name="popVariance")
    
            def batchNormTraining():
                # 一定要使用正确的维度确保计算的是每个特征图上的平均值和方差而不是整个网络节点上的统计分布值
                batchMean, batchVariance = tf.nn.moments(x, [0, 1, 2], keep_dims=False)
    
                decay = 0.99
                trainMean = tf.assign(self.popMean, self.popMean*self.decay + batchMean*(1 - self.decay))
                trainVariance = tf.assign(self.popVariance, self.popVariance*self.decay + batchVariance*(1 - self.decay))
    
                with tf.control_dependencies([trainMean, trainVariance]):
                    return tf.nn.batch_normalization(x, batchMean, batchVariance, beta, gamma, self.epsilon)
    
            def batchNormInference():
                return tf.nn.batch_normalization(x, self.popMean, self.popVariance, beta, gamma, self.epsilon)
    
            batchNormalizedOutput = tf.cond(self.isTraining, batchNormTraining, batchNormInference)
            return tf.nn.relu(batchNormalizedOutput)

     

    8 性能指标函数

      输出分类问题的常用指标。

    # 定义性能指标函数
    
    def mean(item):
        return sum(item) / len(item)
    
    
    def genMetrics(trueY, predY, binaryPredY):
        """
        生成acc和auc值
        """
        
        auc = roc_auc_score(trueY, predY)
        accuracy = accuracy_score(trueY, binaryPredY)
        precision = precision_score(trueY, binaryPredY, average='macro')
        recall = recall_score(trueY, binaryPredY, average='macro')
        
        return round(accuracy, 4), round(auc, 4), round(precision, 4), round(recall, 4)

     

    9 训练模型

      在训练时,我们定义了tensorBoard的输出,并定义了两种模型保存的方法。

    # 训练模型
    
    # 生成训练集和验证集
    trainReviews = data.trainReviews
    trainLabels = data.trainLabels
    evalReviews = data.evalReviews
    evalLabels = data.evalLabels
    
    charEmbedding = data.charEmbedding
    
    # 定义计算图
    with tf.Graph().as_default():
    
        session_conf = tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)
        session_conf.gpu_options.allow_growth=True
        session_conf.gpu_options.per_process_gpu_memory_fraction = 0.9  # 配置gpu占用率  
    
        sess = tf.Session(config=session_conf)
        
        # 定义会话
        with sess.as_default():
            
            cnn = CharCNN(config, charEmbedding)
            globalStep = tf.Variable(0, name="globalStep", trainable=False)
            # 定义优化函数,传入学习速率参数
            optimizer = tf.train.RMSPropOptimizer(config.training.learningRate)
            # 计算梯度,得到梯度和变量
            gradsAndVars = optimizer.compute_gradients(cnn.loss)
            # 将梯度应用到变量下,生成训练器
            trainOp = optimizer.apply_gradients(gradsAndVars, global_step=globalStep)
            
            # 用summary绘制tensorBoard
            gradSummaries = []
            for g, v in gradsAndVars:
                if g is not None:
                    tf.summary.histogram("{}/grad/hist".format(v.name), g)
                    tf.summary.scalar("{}/grad/sparsity".format(v.name), tf.nn.zero_fraction(g))
            
            outDir = os.path.abspath(os.path.join(os.path.curdir, "summarys"))
            print("Writing to {}\n".format(outDir))
            
            lossSummary = tf.summary.scalar("trainLoss", cnn.loss)
            
            summaryOp = tf.summary.merge_all()
            
            trainSummaryDir = os.path.join(outDir, "train")
            trainSummaryWriter = tf.summary.FileWriter(trainSummaryDir, sess.graph)
            
            evalSummaryDir = os.path.join(outDir, "eval")
            evalSummaryWriter = tf.summary.FileWriter(evalSummaryDir, sess.graph)
            
            
            # 初始化所有变量
            saver = tf.train.Saver(tf.global_variables(), max_to_keep=5)
            
            # 保存模型的一种方式,保存为pb文件
            builder = tf.saved_model.builder.SavedModelBuilder("../model/charCNN/savedModel")
            sess.run(tf.global_variables_initializer())
    
            def trainStep(batchX, batchY):
                """
                训练函数
                """   
                feed_dict = {
                  cnn.inputX: batchX,
                  cnn.inputY: batchY,
                  cnn.dropoutKeepProb: config.model.dropoutKeepProb,
                  cnn.isTraining: True
                }
                _, summary, step, loss, predictions, binaryPreds = sess.run(
                    [trainOp, summaryOp, globalStep, cnn.loss, cnn.predictions, cnn.binaryPreds],
                    feed_dict)
                timeStr = datetime.datetime.now().isoformat()
                acc, auc, precision, recall = genMetrics(batchY, predictions, binaryPreds)
                print("{}, step: {}, loss: {}, acc: {}, auc: {}, precision: {}, recall: {}".format(timeStr, step, loss, acc, auc, precision, recall))
                trainSummaryWriter.add_summary(summary, step)
    
            def devStep(batchX, batchY):
                """
                验证函数
                """
                feed_dict = {
                  cnn.inputX: batchX,
                  cnn.inputY: batchY,
                  cnn.dropoutKeepProb: 1.0,
                  cnn.isTraining: False
                }
                summary, step, loss, predictions, binaryPreds = sess.run(
                    [summaryOp, globalStep, cnn.loss, cnn.predictions, cnn.binaryPreds],
                    feed_dict)
                
                acc, auc, precision, recall = genMetrics(batchY, predictions, binaryPreds)
                
                evalSummaryWriter.add_summary(summary, step)
                
                return loss, acc, auc, precision, recall
            
            for i in range(config.training.epoches):
                # 训练模型
                print("start training model")
                for batchTrain in nextBatch(trainReviews, trainLabels, config.batchSize):
                    trainStep(batchTrain[0], batchTrain[1])
    
                    currentStep = tf.train.global_step(sess, globalStep) 
                    if currentStep % config.training.evaluateEvery == 0:
                        print("\nEvaluation:")
                        
                        losses = []
                        accs = []
                        aucs = []
                        precisions = []
                        recalls = []
                        
                        for batchEval in nextBatch(evalReviews, evalLabels, config.batchSize):
                            loss, acc, auc, precision, recall = devStep(batchEval[0], batchEval[1])
                            losses.append(loss)
                            accs.append(acc)
                            aucs.append(auc)
                            precisions.append(precision)
                            recalls.append(recall)
                            
                        time_str = datetime.datetime.now().isoformat()
                        print("{}, step: {}, loss: {}, acc: {}, auc: {}, precision: {}, recall: {}".format(time_str, currentStep, mean(losses), 
                                                                                                           mean(accs), mean(aucs), mean(precisions),
                                                                                                           mean(recalls)))
                        
                    if currentStep % config.training.checkpointEvery == 0:
                        # 保存模型的另一种方法,保存checkpoint文件
                        path = saver.save(sess, "../model/charCNN/model/my-model", global_step=currentStep)
                        print("Saved model checkpoint to {}\n".format(path))
                        
            inputs = {"inputX": tf.saved_model.utils.build_tensor_info(cnn.inputX),
                      "keepProb": tf.saved_model.utils.build_tensor_info(cnn.dropoutKeepProb)}
    
            outputs = {"binaryPreds": tf.saved_model.utils.build_tensor_info(cnn.binaryPreds)}
    
            prediction_signature = tf.saved_model.signature_def_utils.build_signature_def(inputs=inputs, outputs=outputs,
                                                                                          method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME)
            legacy_init_op = tf.group(tf.tables_initializer(), name="legacy_init_op")
            builder.add_meta_graph_and_variables(sess, [tf.saved_model.tag_constants.SERVING],
                                                signature_def_map={"predict": prediction_signature}, legacy_init_op=legacy_init_op)
    
            builder.save()

     

    转载于:https://www.cnblogs.com/jiangxinyang/p/10207686.html

    展开全文
  • 欢迎转载,转载请注明:本文出自Bin的专栏blog....继续前面关于深度学习CNN经典模型的整理,之前介绍了CNN网络Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning(点击查看)的网络结构。 本文讲一下最新由U...

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld。
    技术交流QQ群:433250724,欢迎对算法、技术感兴趣的同学加入。


    继续前面关于深度学习CNN经典模型的整理,之前介绍了CNN网络Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning(点击查看)的网络结构。

    本文讲一下最新由UC Berkeley和Stanford研究人员一起完成的SqueezeNet[1]网络结构和设计思想。SqueezeNet设计目标不是为了得到最佳的CNN识别精度,而是希望简化网络复杂度,同时达到public网络的识别精度。所以SqueezeNet主要是为了降低CNN模型参数数量而设计的。OK,下面直奔主题了。

    设计原则

    (1)替换3x3的卷积kernel为1x1的卷积kernel

    卷积模板的选择,从12年的AlexNet模型一路发展到2015年底Deep Residual Learning模型,基本上卷积大小都选择在3x3了,因为其有效性,以及设计简洁性。本文替换3x3的卷积kernel为1x1的卷积kernel可以让参数缩小9X。但是为了不影响识别精度,并不是全部替换,而是一部分用3x3,一部分用1x1。具体可以看后面的模块结构图。

    (2)减少输入3x3卷积的input feature map数量
    如果是conv1-conv2这样的直连,那么实际上是没有办法减少conv2的input feature map数量的。所以作者巧妙地把原本一层conv分解为两层,并且封装为一个Fire Module。

    (3)减少pooling
    这个观点在很多其他工作中都已经有体现了,比如GoogleNet以及Deep Residual Learning。

    Fire Module

    Fire Module是本文的核心构件,思想非常简单,就是将原来简单的一层conv层变成两层:squeeze层+expand层,各自带上Relu激活层。在squeeze层里面全是1x1的卷积kernel,数量记为S11;在expand层里面有1x1和3x3的卷积kernel,数量分别记为E11和E33,要求S11 < input map number即满足上面的设计原则(2)。expand层之后将1x1和3x3的卷积output feature maps在channel维度拼接起来。

    这里写图片描述

    总体网络架构

    直接上图说(左边的狗狗很忧伤啊):
    这里写图片描述

    看图就很明朗了,总共有9层fire module,中间穿插一些max pooling,最后是global avg pooling代替了fc层(参数大大减少)。在开始和最后还有两层最简单的单层conv层,保证输入输出大小可掌握。

    下图是更详细的说明:非常清楚,就不再啰嗦了。
    这里写图片描述

    实验结果

    主要在imagenet数据上比较了alexnet,可以看到准确率差不多的情况下,squeezeNet模型参数数量显著降低了(下表倒数第三行),参数减少50X;如果再加上deep compression技术,压缩比可以达到461X!还是不错的结果。不过有一点,用deep compression[2]是有解压的代价的,所以计算上会增加一些开销。

    这里写图片描述

    思考

    SqueezeNet之前我就在研究如果降低网络规模,SqueezeNet印证了小得多的网络也可以到达很好的CNN识别精度。相信以后会出现更多小网络,做到state-of-the-art的精度。好,本篇就介绍到这里,希望对大家有启发,有的话请支持一下我博客哈!~谢谢!

    参考资料

    [1] SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size,2016
    [2] Deep compression: Compressing DNNs with pruning, trained quantization and huffman coding, 2015

    转载于:https://www.cnblogs.com/yihaha/p/7265302.html

    展开全文
  • 在机器学习2017年的最新发展中,单任务的网络结构已经逐渐不再引人瞩目,取而代之的是集成,复杂,一石多鸟的多任务网络模型。Mask R-CNN就是典型的代表。本篇大作的一作是何凯明,在该篇论文发表的时候,何凯明已经...
  • 在机器学习2017年的最新发展中,单任务的网络结构已经逐渐不再引人瞩目,取而代之的是集成,复杂,一石多鸟的多任务网络模型。Mask R-CNN就是典型的代表。 大家可以看到,在实例分割MaskR-CNN框架中,还是主要完成了...
  • 在机器学习2017年的最新发展中,单任务的网络结构已经逐渐不再引人瞩目,取而代之的是集成,复杂,一石多鸟的多任务网络模型。Mask R-CNN就是典型的代表。本篇大作的一作是何凯明,在该篇论文发表的时候,何凯明已经...
  • 在机器学习2017年的最新发展中,单任务的网络结构已经逐渐不再引人瞩目,取而代之的是集成,复杂,一石多鸟的多任务网络模型。Mask R-CNN就是典型的代表。本篇大作的一作是何凯明,在该篇论文发表的时候,何凯明已经...
  • 转载原创博文链接。...  Mask R-CNN是ICCV 2017的best paper,彰显了机器...在机器学习2017年的最新发展中,单任务的网络结构已经逐渐不再引人瞩目,取而代之的是集成,复杂,一石多鸟的多任务网络模型。Mask R-CNN...
  • [cv] VGG--CNN经典模型

    2020-02-20 23:45:51
    在图像识别这一方面ImageNet挑战赛会定期产出优秀的模型从最初的 AlexNet 到VGG,RESNet,再到最新的DenseNet。VGG在2014年被提出并拿来参加ImageNet挑战赛,最终实现了92.3%的正确率,得到了当年的亚军。虽然多年...
  • 实例分割模型Mask R-CNN详解 基础深度学习的目标检测技术演进解析 本文转载地址  Mask R-CNN是ICCV 2017的best paper,彰显了机器学习计算机视觉领域在2017年的最新成果。在机器学习2017年的最新发展中,单任务...
  • 近日,云从科技在语音识别技术上取得重大突破,在全球最大的开源语音识别数据集Librispeech上刷新了世界纪录,错词率...本视频课程讲解了:大规模词汇连续语音识别,LVCSR前沿与最新进展,和CNN-pFSMN声学模型
  • CNN浅析和历年ImageNet冠军模型解析

    万次阅读 2017-04-18 21:00:10
    版权声明 作者:黄文坚 本文为大数据杂谈4月13日微信社群分享内容整理。...卷积神经网络(Convolutional Neural Network,CNN)最初是为解决图像识别等问题设计的,当然其现在的应用不仅限于图...
  • CNN

    千次阅读 多人点赞 2016-01-21 22:36:44
    Introduction这是斯坦福计算机...这个课程重点介绍了deep learning里的一种比较流行的模型:Convolutional Neural Networks,简称CNN,主要利用CNN来做visual recognition,或者说是image classification,object recog
  • EVA_Projects:广泛的视觉AI程序,详尽的DNN课程。 此仓库由具有DL模型的项目组成,这些项目使用基于CNN的方法和最新的实现
  • 关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第一 【Python】:排名第三 【算法】:排名第四 前言 在前面我们讲述了DNN的模型与前向反向传播算法。而在DNN大类中,卷积神经网络...
  • 在Pytorch中实现最新的文本分类模型 实施模型 fastText:fastText模型, TextCNN:提出的用于文本分类的CNN TextRNN:用于文本分类的双向LSTM网络 RCNN:在提出的的RCNN模型的实现 CharCNN: 提出的字符级CNN的实现...
  • BERT如今提出来已经很久,基于pre-trained model的研究可以说层出不穷,包括下游任务的应用,学到的权重的解释,压缩模型,knowledge学习等,最新的复旦邱老师关于Pre-trained 模型的综述:...目前可以尝试的方向:M...
  • 模型库,模型库支持CNN等各种经典模型应用,还有Python的API层,基本上其它框架主要也是Python。最底层就是跟硬件打交道的,还有XLA、TVM这些编译器。 天猫转让 中间两层是OneFlow和其他框架差别比较大的地方,...
  • 文章作者:黄浴自动驾驶科学家编辑整理:Hoh Xil内容来源:黄浴@知乎出品平台:DataFunTalk注:文末有最新自动驾驶沙龙,欢迎报名。导读:深度学习自从2006年以后已经 "火" 了十多年了,目前大家看到的,最普遍的...
  • 共同近邻(CNN)聚类 笔记 该项目目前处于Alpha状态。 将来可能会更改实现。 检查示例和文档以获取最新信息。 集群 所述cnnclustering Python包提供了一个灵活的接口聚类算法使用C ommon-Ñearest-Ñeighbours。 ...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 230
精华内容 92
关键字:

最新cnn模型