【cola】TF学习小组总结


#1

刚刚开始接触深度学习,为职业方向打下基础!


#2

#Week 1 ##实践任务 ###a. tensorflow 安装 参考了http://blog.csdn.net/jay100500/article/details/72809338 在win10下成功安装了python 3.6 tensorflow1.2.1-cpu版本以及sypder3环境

###b.使用tf计算下面算式的值: x=2 ,y=3,z=7 求解:res=x*y+z的结果

 import tensorflow as tf
 x=tf.constant(2)
 y=tf.constant(3)
 z=tf.constant(7)
 with tf.Session() as sess:
    res=sess.run(x*y+z)
    print("res=%d"%res)

结果截图

###c.使用tf计算求解,矩阵乘法结果: 矩阵乘法:A :[[3., 3.]] B: [[2.],[2.]] A矩阵和B矩阵的乘法运算。

import tensorflow as tf
A=tf.constant([[3., 3.]])
B=tf.constant([[2.],[2.]])
res=tf.matmul(A,B)
with tf.Session() as sess:
    print("res=%d"%sess.run(res))

结果截图


#3

#Week 1 ##理论学习 ###1、机器器学习中,监督学习 or 非监督学习概念区分,应用场景调研? 监督学习:人为设定训练集,即训练数据已经人为标注对应的训练结果,比如神经网络,KNN等 无监督学习:没有对样本进行预处理,直接建模,比如聚类,FMM等 计算相关度,相似性的模型采用无监督学习 目标分类,检测采用监督学习 ###2、做机器学习项目,有哪些环节? 确定项目的输入和输出,制定数据集,建立数学模型,计算结果,计算准确度,重新调整模型 ###3、深度学习,目前有哪些应用领域? 图像:图像分类,语义分割,目标跟踪 数据:大数据预测,音乐推荐 ###4、数据预处理,需要注意哪些? 数据带有噪声,数据不完整,数据不一致,需要数据清洗。一般还要数据标准化 ###5、tensorflow运行行原理,架构有哪些核心点? tensorflow的架构:用张量tensor表示数据;计算图graph表示任务;在会话session中执行操作;
通过变量维护状态;通过feed和fetch可以任意的操作(arbitrary operation)、赋值、获取数据。 参考了博客:http://blog.csdn.net/sinat_26917383/article/details/54667692


#4

#Week 2 ##实践任务 ###a.使用tf实现Logistic Regression算法 参考了一些同学代码后,使用mnist数据集和tensorflow自带mnist读取函数实现手写数字逻辑回归

# -*- coding: utf-8 -*-
import tensorflow as tf

# 导入input_data用于自动下载
from tensorflow.examples.tutorials.mnist import input_data
# 安装MNIST数据集
mnist = input_data.read_data_sets('../MNIST_data', one_hot=True)

# 一些参数
training_epochs = 20
batch_size = 50

# 建立占位符

# mnist图像数据 28*28=784
x = tf.placeholder(tf.float32, [None, 784])

# 图像类别,总共10类
y = tf.placeholder(tf.float32, [None, 10])

#创建两个变量,分别用来存放权重值W和偏置值b
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

# 使用Tensorflow提供的回归模型softmax,y代表输出
pre = tf.nn.softmax(tf.matmul(x, W) + b)

# reduce_sum 对所有类别求和,reduce_mean 对和取平均
loss = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pre), reduction_indices=1))

# 计算梯度
optimizer = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

correct_prediction = tf.equal(tf.argmax(pre, 1), tf.argmax(y, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # 训练模型
    for epoch in range(training_epochs):
        total_batch = int(mnist.train.num_examples/batch_size)
        for i in range(total_batch):
            batch = mnist.train.next_batch(batch_size)
            _, c = sess.run([optimizer,loss], feed_dict={x: batch[0],y: batch[1]})
        train_accuracy = accuracy.eval(feed_dict={x:batch[0], y:batch[1]})
        print('Epoch:%d   loss:%f  accuracy:%f' % (epoch+1,c,train_accuracy))

    print("Done")
    
    # 计算测试集正确率
    print("Test Accuracy:", accuracy.eval({x: mnist.test.images[:3000], y: mnist.test.labels[:3000]}))

结果:


#5

加油,week 3的作业,更有意思!


#6

#Week 2 ##实践任务 ###b.使用tf对Kaggle泰坦尼克之灾数据预测 参考了学员Pitt的代码,并进行了修改 其中使用了性别,年龄,和客舱位置三个特征对最后能否逃出游轮进行预测

import pandas as pd
import tensorflow as tf
 # 读取数据csv
data = pd.read_csv('C:\\Users\\Javid\\Desktop\\train.csv')
 # 数据预处理
 # 1. 性别转换为0,1表示
 # 2. 年龄补零
data['Sex'] = data['Sex'].apply(lambda x: 1 if x == 'male' else 0)
data = data.fillna(0)
 # 取舱位,性别,年龄
data_X = data[['Pclass', 'Sex', 'Age']]
dataset_X = data_X.as_matrix()
 # 整理标签集合,形成one-hot编码
data['Deceased'] = data['Survived'].apply(lambda s: 1 - s) 
data_Y = data[['Deceased', 'Survived']]
dataset_Y = data_Y.as_matrix()
 # 将训练数据切分为“训练数据集和验证数据集”
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(dataset_X, dataset_Y, test_size = 0.2, random_state = 42)
 # 建立占位符
X = tf.placeholder(tf.float32, shape=[None, 3], name='input')
y = tf.placeholder(tf.float32, shape=[None, 2], name='label')
 # 设置参数变量
W = tf.Variable(tf.random_normal([3, 2]), name='weights')
b = tf.Variable(tf.zeros([2]), name='bias')
 # 逻辑回归
y_pred = tf.nn.softmax(tf.matmul(X, W) + b)
 # 交叉熵
cross_entropy = - tf.reduce_sum(y * tf.log(y_pred + 1e-10), reduction_indices=1)
 # 损失函数
loss = tf.reduce_mean(cross_entropy)
 # 使用随机梯度下降算法优化
train_op = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
#定义正确率
correct = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y_val, 1))
accuracy =tf.reduce_mean(tf.cast(correct, tf.float32))
#计算图
with tf.Session() as sess:
    # 初始化
    tf.global_variables_initializer().run()
    # 训练,epoch=40
    for epoch in range(40):
        total_loss = 0.
        for i in range(len(X_train)):
            _, loss_ = sess.run([train_op, loss], feed_dict={X: [X_train[i]], y: [y_train[i]]})
            total_loss += loss_
        acc=accuracy.eval(feed_dict={X: X_val})
        print('Epoch: %04d, total loss=%.4f,accuracy :%.4f'% (epoch + 1, total_loss,acc))
    print('Training complete!')


#7

#Week 2 ##理论学习 ###1.back propagation算法原理理解 参考博客:http://blog.csdn.net/shijing_0214/article/details/51923547

通过上图可以看到,正向微分算法根据路径的传播方向,依次计算路径中的各结点对输入X的偏导数,结果中保留了输入对各结点的影响。 我们再看下反向微分算法: 可以看到,该算法从后向前进行计算,结果中保留了路径中各结点对输出的影响。 利用正向微分算法,我们得到关于变量b的偏导计算结果如下: 而利用反向微分算法,我们得到的偏导计算结果如下: 可以看出,反向微分算法保留了所有变量包括中间变量对结果e的影响。若e为误差函数,则对图进行一次计算,则可以得出所有结点对e的影响,也就是梯度值,下一步就可以利用这些梯度值来更新边的权重;而正向微分算法得到的结果是只保留了一个输入变量对误差e的影响,显然,想要获得多个变量对e的影响,我们就需要进行多次计算,所以正向微分算法在效率上明显不如反向微分,这也是我们选择反向微分算法的原因。 ###2.sigmoid函数、tanh函数和ReLU函数的区别?以及各自的优缺点?对应的tf函数是? ① **优点:**把连续的输入转化映射到0~1之间,方便后续计算,也可用作网络输出的概率分布 **缺点:**sigmoid 有一个非常致命的缺点,当输入非常大或者非常小的时候(saturation),这些神经元的梯度是接近于0的,从图中可以看出梯度的趋势。所以,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。还有Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。 产生的一个结果就是:如果数据进入神经元的时候是正的(e.g. x>0 elementwise in f=wTx+b),那么 w 计算出的梯度也会始终都是正的。 (这个问题可以由batch来弥补) ② tanh 是sigmoid的变形: tanh(x)=2sigmoid(2x)−1 与 sigmoid 不同的是,tanh 是0均值的。因此,实际应用中,tanh 会比 sigmoid 更好 **优点:**tanh的输出和输入能够保持非线性单调上升和下降关系,继承了sigmoid的优点 **缺点:**只是sigmoid的优化,计算量大 ③ Relu:f(x)=max(0,x) **优点:**Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生 参考博客:http://blog.csdn.net/suixinsuiyuan33/article/details/69062894?locationNum=4&fps=1 ###3.softmax和cross_entropy原理 softmax softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!假设我们有一个数组,V,Vi表示V中的第i个元素 那么这个元素的softmax值就是: 更形象的如下图表示: cross_entropy 定义:在信息论中,交叉熵是表示两个概率分布p,q,其中p表示真实分布,q表示非真实分布,在相同的一组事件中,其中,用非真实分布q来表示某个事件发生所需要的平均比特数。 对于离散变量采用以下的方式计算: 对于连续变量采用以下的方式计算: 参考博客:https://www.cnblogs.com/ljy2013/p/6432269.html


#8

###4.tf.placeholder() 、tf.constant()、tf.Variable()的区别 ①tf.placeholder() 是占位符,为预留空间,需要其他数据进行供给 ②tf.constant()直接把常数转为tensorflow格式,是不可变得 ③tf.Variable()是创建变量空间,为网络参数提供变量,是可变的 ###5.tf.Graph()概念 一个TensorFlow的运算,被表示为一个数据流的图。 一幅图中包含一些操作(Operation)对象,这些对象是计算节点。 你一旦开始你的任务,就已经有一个默认的图已经创建好了。而且可以通过调用tf.get_default_graph()来访问到。 添加一个操作到默认的图里面,只要简单的调用一个定义了新操作的函数就行。比如下面的例子展示的:

import tensorflow as tf
import numpy as np

c=tf.constant(value=1)
#print(assert c.graph is tf.get_default_graph())
print(c.graph)
print(tf.get_default_graph())

另外一种典型的用法就是要使用到Graph.as_default() 的上下文管理器( context manager),它能够在这个上下文里面覆盖默认的图。如下例

import tensorflow as tf
import numpy as np

c=tf.constant(value=1)
#print(assert c.graph is tf.get_default_graph())
print(c.graph)
print(tf.get_default_graph())

g=tf.Graph()
print("g:",g)
with g.as_default():
    d=tf.constant(value=2)
    print(d.graph)
    #print(g)

g2=tf.Graph()
print("g2:",g2)
g2.as_default()
e=tf.constant(value=15)
print(e.graph)

一个Graph的实例支持任意多数量通过名字区分的的“collections”。 为了方便,当构建一个大的图的时候,collection能够存储很多类似的对象。比如 tf.Variable就使用了一个collection(tf.GraphKeys.GLOBAL_VARIABLES),包含了所有在图创建过程中的变量。 也可以通过之指定新名称定义其他的collection 参考博客:http://blog.csdn.net/xierhacker/article/details/53860379 ###6.tf.name_scope()和tf.variable_scope()的理解 例1:

with tf.name_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

例2

with tf.variable_scope("my_scope"):
    v1 = tf.get_variable("var1", [1], dtype=tf.float32)
    v2 = tf.Variable(1, name="var2", dtype=tf.float32)
    a = tf.add(v1, v2)

print(v1.name)  # my_scope/var1:0
print(v2.name)  # my_scope/var2:0
print(a.name)   # my_scope/Add:0

name_scope及variable_scope的作用都是为了不传引用而访问跨代码区域变量的一种方式,其内部功能是在其代码块内显式创建的变量都会带上scope前缀(如上面例子中的a),这一点它们几乎一样。而它们的差别是,在其作用域中获取变量,它们对 tf.get_variable() 函数的作用是一个会自动添加前缀,一个不会添加前缀。 参考:https://www.cnblogs.com/welhzh/p/6590212.html ###7、tf.variable_scope() 和tf.get_variable()的理解 tf.get_variable 和tf.Variable不同的一点是,前者拥有一个变量检查机制,会检测已经存在的变量是否设置为共享变量,如果已经存在的变量没有设置为共享变量,TensorFlow 运行到第二个拥有相同名字的变量的时候,就会报错。 为了解决这个问题,TensorFlow 又提出了 tf.variable_scope 函数:它的主要作用是,在一个作用域 scope 内共享一些变量,可以有如下几种用法:

with tf.variable_scope("image_filters") as scope:
    result1 = my_image_filter(image1)
    scope.reuse_variables() # or 
    #tf.get_variable_scope().reuse_variables()
    result2 = my_image_filter(image2)

with tf.variable_scope("image_filters1") as scope1:
    result1 = my_image_filter(image1)
with tf.variable_scope(scope1, reuse = True)
    result2 = my_image_filter(image2)

参考博客:http://www.cnblogs.com/Charles-Wan/p/6200446.html ###8.tf.global_variables_initializer() 什么时候使用 global_variables_initializer 返回一个用来初始化 计算图中 所有global variable的 op。 在tf.Session()执行训练之前使用参数初始化 解析: 函数中调用了 variable_initializer() 和 global_variables() global_variables() 返回一个 Variable list ,里面保存的是 gloabal variables。 variable_initializer() 将 Variable list 中的所有 Variable 取出来,将其 variable.initializer 属性做成一个 op group。然后看 Variable 类的源码可以发现, variable.initializer 就是一个 assign op。 所以: sess.run(tf.global_variables_initializer()) 就是 run了 所有global Variable 的 assign op,这就是初始化参数的本来面目。


#9

#Week 3 ##实践任务 a.在mnist手写数字数据集上,使用LeNet5模型进行训练和测试,评估准确率 这里对tensorflow的mnist教程进行了修改,增加了一层全连接层,修改了部分参数

import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('../MNIST_data', one_hot=True)
#输入占位符
x = tf.placeholder(tf.float32, [None, 784])                        #输入的数据占位符
y = tf.placeholder(tf.float32, shape=[None, 10])            #输入的标签占位符
#定义一个函数,用于初始化所有的权值 W
def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

#定义一个函数,用于初始化所有的偏置项 b
def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)
  
#定义一个函数,用于构建卷积层
def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
 
#定义一个函数,用于构建池化层
def max_pool(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')
#构建网络
x_image = tf.reshape(x, [-1,28,28,1])         #转换输入数据shape,以便于用于网络中
W_conv1 = weight_variable([5, 5, 1, 32])      
b_conv1 = bias_variable([32])       
h_conv1 = tf.nn.relu(conv2d( x_image, W_conv1) + b_conv1)     #第一个卷积层
h_pool1 = max_pool(h_conv1)                                  #第一个池化层

W_conv2 = weight_variable([5, 5, 32, 64])

b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)      #第二个卷积层
h_pool2 = max_pool(h_conv2)                                   #第二个池化层

W_fc1 = weight_variable([7 * 7 * 64, 120])
b_fc1 = bias_variable([120])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])              #reshape成向量
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)    #第一个全连接层

W_fc2 = weight_variable([120,84])
b_fc2 = bias_variable([84])
h_fc2 = tf.nn.relu(tf.matmul(h_fc1, W_fc2) + b_fc2)    #第二个全连接层
keep_prob = tf.placeholder("float") 
h_fc1_drop = tf.nn.dropout(h_fc2, keep_prob)                  #dropout层
#######
W_fc3 = weight_variable([84, 10])
b_fc3 = bias_variable([10])
y_predict=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc3) + b_fc3)   #softmax层

cross_entropy = -tf.reduce_sum(y*tf.log(y_predict))     #交叉熵
train_step = tf.train.GradientDescentOptimizer(1e-3).minimize(cross_entropy)    #梯度下降法
correct_prediction = tf.equal(tf.argmax(y_predict,1), tf.argmax(y,1))    
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))                 #精确度计算
sess=tf.InteractiveSession()                          
sess.run(tf.initialize_all_variables())
for i in range(6000):
  batch = mnist.train.next_batch(50)
  if i%100 == 0:                  #训练100次,验证一次
    train_acc = accuracy.eval(feed_dict={x:batch[0], y: batch[1], keep_prob: 1.0})
    print('step',i,'training accuracy',train_acc)
  train_step.run(feed_dict={x: batch[0], y: batch[1], keep_prob: 0.5})

test_acc=accuracy.eval(feed_dict={x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0})
print("test accuracy",test_acc)

##运行结果


#10

#Week 3 ##理论学习 ###1.Batch Normalization 原理解释&优点 ###介绍 BN的来源:文献《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》 学习率、参数初始化、权重衰减系数、Drop out比例等方法已经应用至各大网络模型当中,加速收敛,避免梯度消失有极大的效果改善。在这些之上出现了Batch Normalization方法。 BN层是对于每个神经元做归一化处理,甚至只需要对某一个神经元进行归一化,而不是对一整层网络的神经元进行归一化。 ###公式 文章引入了可学习参数γ、β 每一个神经元xk都会有一对这样的参数γ、β。有: BN的前向传播公式: 举例来说:卷积神经网络经过卷积后得到的是一系列的特征图,如果min-batch sizes为m,那么网络某一层输入数据可以表示为四维矩阵(m,f,p,q),m为min-batch sizes,f为特征图个数,p、q分别为特征图的宽高。在cnn中我们可以把每个特征图看成是一个特征处理(一个神经元),因此在使用Batch Normalization,mini-batch size 的大小就是:mpq,于是对于每个特征图都只有一对可学习参数:γ、β。说白了吧,这就是相当于求取所有样本所对应的一个特征图的所有神经元的平均值、方差,然后对这个特征图神经元做归一化。 ###优点 BN的提出是为了克服深度神经网络难以训练的弊病,解决的是反向传播过程中的梯度问题,加快收敛。 #####参考博客: http://blog.csdn.net/hjimce/article/details/50866313 https://www.zhihu.com/question/38102762 ###2.如何理解卷积 卷积的重要的物理意义是:一个函数(如:单位响应)在另一个函数(如:输入信号)上的加权叠加。学过信号与系统的同学知道,就常识来讲,系统的响应不仅与当前时刻系统的输入有关,也跟之前若干时刻的输入有关,因为我们可以理解为这是之前时刻的输入信号经过一种过程(这种过程可以是递减,削弱,或其他)对现在时刻系统输出的影响,那么显然,我们计算系统输出时就必须考虑现在时刻的信号输入的响应以及之前若干时刻信号输入的响应之“残留”影响的一个叠加效果。 深度学习中卷积把这种加权叠加作为特征进行选取,可见是对连续输入的数据进行加权叠加。 #####参考博客 http://blog.csdn.net/bitcarmanlee/article/details/54729807 https://www.zhihu.com/question/22298352


#11

#Week3 ###3.如何理理解卷积神经网络(CNN)中的卷积(Convolution Kernel)和池化(Pooling)&有哪些Pooling ####卷积 CNN中的卷积的核心思想是构建n个aa的模板,通过滑动窗口的形式,逐个对原始数据进行模板的矩阵乘法运算,从而得到n个特征图(featuremap)。以下为李宏毅教程中的例子: ####池化 池化是对输入的特征图进行压缩,一方面使特征图变小,简化网络计算复杂度;一方面进行特征压缩,提取主要特征。 池化操作一般有两种,一种是Average Pooling,一种是Max Pooling 第一种是用bb的模板对数据进行滑动窗口计算,把其中bb的元素计算均值,并把该b维的数据转为1维,且用均值替代。第二种是把bb大小的窗中的最大值输出。 例如:当stride=2时 经过Max pooling可以得到 ###4.Learning Rate 的如何选取,它过大/过小会产生什什么影响? 学习率是直接影响网络收敛的条件之一,它直接影响梯度的大小。学习率过大,梯度变化过快,可能使网络参数更新跳过了收敛区域,导致网络不收敛。学习过小,学习十分缓慢,算法可能经过大量的训练仍然在收敛,但达不到全部最小。现在一般的learning rate视训练实际效果来定,如果不收敛就调小学习率。还有就是学习率分级调速,让训练数据学习率一开始比较大,训练过半后,学习率0.1,快结束了时0.1之类。 ###5.机器器学习中,有哪些正则化的方法,目的是什么,Dropout的好处? ####正则化: 加入正则项的目的是为了避免过拟合。正则项一般为范数L0 L1 L2。 下面的博客有详细介绍,就不在赘述。 http://blog.csdn.net/zouxy09/article/details/24971995 ####Dropout Dropout是对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。目的是避免过拟合,同时由于减少了一部分参数更新,它加速了网络训练。 ###6.Covariate Shift 和 Internal Covariate Shift 如何理理解? ####Covariate Shift介绍 假设q1(x)是测试集中一个样本点的概率密度,q0(x)是训练集中一个样本点的概率密度。最终我们估计一个条件概率密度p(y|x,θ),它由x和一组参数θ={θ1,θ2…θm}所决定。对于一组参数来说,对应loss(θ)函数评估性能的好坏 综上,当我们找出在q0(x)分布上最优的一组θ’时,能否保证q1(x)上测试时也最好呢? 传统机器学习假设训练集和测试集是独立同分布的,即q0(x)=q1(x),所以可以推出最优θ’依然可以保证q1(x)最优。但现实当中这个假设往往不成立,伴随新数据产生,老数据会过时,当q0(x)不再等于q1(x)时,就被称作covariate shift ####internal covariate shift 神经网络在训练时候,每一层的输入的分布都在发生变化(训练时候,网络的参数会更新),这就要求网络的初始化权重不能随意设置,而且学习率也比较低。因此,我们很难使用饱和非线性部分去做网络训练,作者称这种现象为internal covariate shift 。

这两个都算是batch normalization的问题 参考博客: http://blog.csdn.net/wty__/article/details/52583575 http://blog.csdn.net/mao_xiao_feng/article/details/54317852


#12

#Week3 ###7.如何理理解Momentum ?weight decay?它们在神经网络训练中的作用是什么? ####momentum momentum是梯度下降法中一种常用的加速技术。对于一般的SGD,其表达式为,沿负梯度方向下降。而带momentum项的SGD则写生如下形式: 其中 即momentum系数,通俗的理解上面式子就是,如果上一次的momentum(即)与这一次的负梯度方向是相同的,那这次下降的幅度就会加大,所以这样做能够达到加速收敛的过程。 ####weight decay weight decay(权值衰减)的使用是防止过拟合。在损失函数中,weight decay是放在正则项(regularization)前面的一个系数,正则项一般指示模型的复杂度,所以weight decay的作用是调节模型复杂度对损失函数的影响,若weight decay很大,则复杂的模型损失函数的值也就大。

参考链接:https://www.zhihu.com/question/24529483


#13

###8、如何理解“过拟合 overfitting”? 神经网络训练,如何避免overfitting? 过拟合就是在网络复杂的情况下,网络严格记住了每个输入对应输出的结果,从而没有了泛化性。 深度学习中避免过拟合的方法有1.dropout 2.batchnormalizaiton 3.正则化 4.增加数据集 5.手动设定训练次数,提早在过拟合前停止迭代,只保留之前的收敛结果。


#14

###9、各种优化方法(SGD/Momentum/Adagrad/Adam等),对比优缺点 ####SGD: SGD就是每一次迭代计算mini-batch的梯度,然后对参数进行更新,是最常见的优化方法了。 公式: 其中,是学习率,是梯度 SGD完全依赖于当前batch的梯度 优点: 通用,速度快 缺点: 1.选择合适的learning rate比较困难 - 对所有的参数更新使用同样的learning rate。对于稀疏数据或者特征,有时我们可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD就不太能满足要求了。 2.SGD容易收敛到局部最优,并且在某些情况下可能被困在鞍点【原来写的是“容易困于鞍点”,经查阅论文发现,其实在合适的初始化和step size的情况下,鞍点的影响并没这么大。 ####Momentum: momentum是模拟物理里动量的概念,积累之前的动量来替代真正的梯度。 公式: 是动量因子 优点: 1.下降初期时,使用上一次参数更新,下降方向一致,乘上较大的μ能够进行很好的加速 2.下降中后期时,在局部最小值来回震荡的时候,,μ使得更新幅度增大,跳出陷阱 3.在梯度改变方向的时候,μ能够减少更新 总而言之,momentum项能够在相关方向加速SGD,抑制振荡,从而加快收敛 ####Adagrad: Adagrad其实是对学习率进行了一个约束。即: 此处,对从1到t进行一个递推形成一个约束项regularizer,用来保证分母非0 优点: 1.前期较小的时候, regularizer较大,能够放大梯度 2.后期较大的时候,regularizer较小,能够约束梯度 3.适合处理稀疏梯度 缺点: 1.只有人工设定的一个全局学习率 2.中后期,分母上梯度平方的累加将会越来越大,使,使得训练提前结束 ####Adam: Adam(Adaptive Moment Estimation)本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。公式如下: 其中,mt,nt分别是对梯度的一阶矩估计和二阶矩估计,可以看作对期望的估计;是对mt,nt的校正,这样可以近似为对期望的无偏估计。 可以看出,直接对梯度的矩估计对内存没有额外的要求,而且可以根据梯度进行动态调整,而对学习率形成一个动态约束,而且有明确的范围 优点: 1.结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点 2.对内存需求较小 3.为不同的参数计算不同的自适应学习率 4.也适用于大多非凸优化 - 适用于大数据集和高维空间 ####除了以上几个优化方法还有:Nesterov,Adadelta,RMSprop,Adamax,Nadam。 参考博客:https://zhuanlan.zhihu.com/p/22252270


#15

###10.Lenet-5网络详细解释

网络由一个输入层,两个卷积层,两个下采样层,两个全链接层,一个输出层组成。 输入图像3232; 第一次卷积是用深度为6维,感受野为55的卷积模板,得到特征图像28286,第一次池化后得到图像14146; 第二次卷积是用深度为16维,感受野为55的卷积模板,得到图像101016,第二次池化后得到图像55*16; 第一次全连接层是把第二次池化后的图像,转为特征向量,加入120个偏置 第二次全连接层是把第一次全连接层后的向量,加入84个偏置 输出层是把第二次全连接层的输出转化为10维输出。

参考博客:http://blog.csdn.net/qiaofangjie/article/details/16826849