【zxca368】TF学习小组总结_Week2

深度学习

#1

Week2

1. 推荐内容学习

1.0 线性回归Linear Regression

${f_{w,b}(x) }=\sum_{i} w_ix_i+b$ 各个feature的 Xi 对应的权重 Wi 相乘并求和, 再最后加上b, 不通过Sigmod函数计算, 输出值是任意范围的值。

  • 误差估计 $\hat{y}^n : $ 代表数据真实值 , $f(x^n)$ 代表预测值, $\frac{1}{2}\sum_{i=1}^{n}{(预测结果_i - 实际结果_i )^2}$ 使用均方误差用来衡量, 有着很好地几何特性,和二范数一样。 前面乘上的1/2是为了在求导的时候,这个系数就不见了。

1.1 逻辑回归 Logistic Regression

  • 线性 $z=\sum_{i} w_ix_i+b$ 通过 Sigmod 函数 $\sigma(z)$ 转为非线性 logistic回归本质上是线性回归,只是在特征到结果的映射中加入了一层函数映射,即先把特征线性求和,然后使用函数 $\sigma(z)$ 将最为假设函数来预测。$\sigma(z)$ 可以将连续值映射到0和1上。

${f_{w,b}(x) }=\sigma(\sum_{i} w_ix_i+b)$

上面公式在线性回归的基础上, 将线性回归的结果带入Sigmod函数中, 得到的结果介于 0 到 1 之间。

$P_{w,b}(C_1|x)=\sigma(z),\sigma(z)=\frac{1}{1+\exp(-z)}, z=w*x +b = \sum_iw_ix_i+b $

将$z$带入Sigmod函数——> $\sigma(z)$ 得到概率大小。

$f_{w,b}(x) = P_{w,b}(C_1|x)$ 表示在Sigmod函数的映射下 , $C_1$的概率大小。

从该式可以看出, 最后$f_{w,b}(x)$的结果受到 $w、b$ 两个参数的控制, 可以选择不同的 $w$ 和 $b$ 得到不同的Function,计算出C1的概率。

  • 损失函数

误差公式: $L(w,b) = f_{w,b}(x^1)f_{w,b}(x^2)*f_{w,b}(x^n)$ 每个$x_i$ 对应的概率 $f_{w,b}=(x^i)$ 连续相乘, 其中 $W,b$ 就是能够是的 $L(w,b) $最大化的一组值。

$w^{\star},b^{\star}=\arg \max_{w,b}L(w,b) = w^{\star},b^{\star}=\arg \min - lnL(w,b)$

等式右边的 $-log$ 以 $e$ 为底的对数形式的好处就是相乘变成现在相加 即: $-lnL(w,b) =-lnf_{w,b}(x^1)-lnf_{w,b}(x^2)+…+(-lnf_{w,b}(x^n))$

【伯努利分布】 如果 $\hat{y}^n$ = 0 or 1 , 即满足伯努利分布 伯努利分布亦称“零一分布”、“两点分布”。称随机变量X有伯努利分布, 参数为p(0<p<1),如果它分别以概率p和1-p取1和0为值。EX= p,DX=p(1-p)。伯努利试验成功的次数服从伯努利分布,参数p是试验成功的概率。伯努利分布是一个离散型机率分布,是N=1时二项分布的特殊情况。 【交叉熵】](https://www.zhihu.com/question/65288314/answer/244601417) 交叉熵 Cross entropy 代表着 p 、 q分布有多接近, 如果两个分布式一样的,那么交叉熵结果为0

损失函数: $L(f) = \sum_nC(f(x^n),\hat{y^n})$

$C(f(x^n),\hat{y}^n) = -[\hat{y}^1lnf(x^1)+(1-\hat{y}^1)ln(1-f(x^1))$

【问题:】逻辑回归中的误差公式, 为什么不直接像线性回归一样使用平方误差做误差公式?

【回答: 】 在Step3步骤中,对$L(w,b) = f_{w,b}(x^1)f_{w,b}(x^2)***f_{w,b}(x^n)$ 做 $w_i$偏微分, 会出现无论在距离目标的远近, 微分结果都有可能是0, 造成最后结果的错误。

逻辑回归中, 采用交叉熵作为误差公式, 如果距离目标点越远, 相应的微分值就越大。

  • 生成模型 V.S. 判别模型 监督学习方法又可分为生成方法和判别方法。所学到的模型分别称为生成模型和判别模型。

生成模型(Genertive Model) 需要提前假设训练数据服从某种分布(伯努利、混合高斯模型、朴素贝叶斯),生成方法由数据学习联合概率分布 $P(X|Y)$ ,然后求出条件概率分布 $P(Y|X)$ 作为预测模型,即生成模型:$P(Y|X) = \frac{P(X,Y)}{P(X)}$ , 模型表示了给定输入X产生输出Y的生成关系。

判别模型(Discriminative Model) 直接学习的是条件概率 $P(Y|X)$ 或者决策函数 $f(X)$ 直接面对预测,往往学习的准确率更高,常见方法有SVM, LR等。

多分类, 中间求和, 输出结果做除法运算, 得到输出结果 介于0到1之间。

softmax直白来说就是将原来输出是3,1,-3通过softmax函数一作用,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们就可以将它理解成概率,在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标!

  • 一条线有时候, 不能完全将两类分隔开
  • 需要对原有数据做特征转换
  • 在特征转换的基础上, 再将多个逻辑回归模型拼接起来, 特征转换后的输出结果, 作为下一层逻辑回归模型的输入。

2. 思考问题:

2.1 back propagation 算法原理理解 ?

http://blog.csdn.net/mao_xiao_feng/article/details/53048213

2.2 sigmoid函数、tanh函数和ReLU函数的区别?以及各自的优缺点?对应的tf函数是?

这三个都是非线性激励函数, 为什么引入非线性激励函数?

如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是最原始的感知机(Perceptron)。

正因为上面的原因,决定引入非线性函数作为激励函数,这样深层神经网络就有意义了(不再是输入的线性组合,可以逼近任意函数)。最早的想法是sigmoid函数或者tanh函数,输出有界,很容易充当下一层输入。

激活函数(Activation Function)的特点:

  • 非线性: 当激活函数是线性的时候,一个两层的神经网络就可以逼近基本上所有的函数了。

  • 可微: 当优化方法是基于梯度的时候,这个性质是必须的。

  • 单调性: 当激活函数是单调的时候,单层网络能够保证是凸函数。

  • f(x)≈x: 当激活函数满足这个性质的时候,如果参数的初始化是random的很小的值,那么神经网络的训练将会很高效。

  • 输出值范围: 当激活函数输出值是 有限 的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是 无限 的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的学习率。

  • Sigmod

  • 公式: $f(x)=\frac{1}{1+e^{-z}}$

  • 图像:

  • 优点: 可将任意值变换到01区间, 可做概率; 它还是便于求导的平滑函数,其导数为 $\sigma(x)(1-\sigma(x))$

  • 缺点:

    • 容易出现梯度消失gradient vanishing, 在反向传播算法中, Sigmod函数求导越来越小, 最后会发生梯度消失。ReLU导数是常数, 因此可以解决梯度消失问题。
    • 函数输出并不是零均值的zero-centered, Sigmoid函数的输出值恒大于0,这会导致模型训练的收敛速度变慢。
    • 幂运算相对来讲比较耗时
  • tf函数 tf.sigmoid(x, name=None)

  • Tanh

  • 公式: $\quad tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} = 2sigmod(2x) -1$

  • 图片:

  • 优点: tanh读作Hyperbolic Tangent,如上图所示,tanh 是0均值的, 它解决了不是零均值的输出问题,。因此,实际应用中,tanh 会比 sigmoid 更好。

  • 缺点: 梯度消失的问题和幂运算的问题仍然存在。

  • tf函数 tf.tanh(x, name=None)

  • ReLU

  • 数学公式: $ReLU=f(x)=max(0, x)$

  • tf函数 tf.nn.relu(features, name=None)

  • 二维数据的时候: 从图左可以看出,输入信号<0时,输出都是0,>0 的情况下,输出等于输入。w 是二维的情况下,使用ReLU之后的效果如下:

  • 优点

    • 解决了gradient vanishing问题 (在正区间)
    • ReLU 得到的SGD的收敛速度会比 sigmoid/tanh 快很多(看右图)。计算速度非常快,只需要判断输入是否大于0
    • 收敛速度远快于sigmoid和tanh
  • 缺点

  • ReLU的输出不是zero-centered

  • Dead ReLU Problem 神经元死亡问题,指的是某些神经元可能永远不会被激活。

  • tf函数 tf.nn.relu(features, name=None)

2.3 softmax和cross_entropy原理解释?

  • softmax softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,输出结果(概率)和为1, 可以看成概率来理解,从而来进行多分类!

  • cross_entropy 交叉熵,信息学理论中的概念,用来衡量两个分布之间的相似程度,值越小,越相似。当两者一样时,熵为0。

  • softmax 和 sigmod的区别

    • sigmoid将一个real value映射到(0,1)的区间(当然也可以是(-1,1)),这样可以用来做二分类。

    • softmax把一个k维的real value向量(a1,a2,a3,a4….)映射成一个(b1,b2,b3,b4….)其中bi是一个0-1的常数,然后可以根据bi的大小来进行多分类的任务,如取权重最大的一维。

2.4 tf.placeholder() 、tf.constant()、tf.Variable()的区别?

  • tf.placeholder()

  • 用于得到传递进来的真实的训练样本, 是个占位符。

  • 不必指定初始值,可在运行时,通过 Session.run 的函数的 feed_dict 参数指定

  • tf.constant()

    • tf.constant(value, dtype=None, shape=None, name=‘Const’, verify_shape=False) 作用:创建一个常量tensor 参数: value: 一个dtype类型(如果指定了)的常量值(列表)。要注意的是,要是value是一个列表的话,那么列表的长度不能够超过形状参数指定的大小(如果指定了)。要是列表长度小于指定的,那么多余的由列表的最后一个元素来填充。 dtype: 返回tensor的类型 shape: 返回的tensor形状。 name: tensor的名字 verify_shape: Boolean that enables verification of a shape of values.
  • tf.Variable()

    • 通过构造一个Variable类的实例在图中添加一个变量,主要在于一些可训练变量(trainable variables),比如模型的权重(weights,W)或者偏执值(bias)
    • 构造函数需要初始值,这个初始值可以是一个任何类型任何形状的Tensor,初始值的形状和类型决定了这个变量的形状和类型。

2.5 举例说明:tf.Graph() 概念理解?

一个TensorFlow的运算,被表示为一个数据流的图。一幅图中包含一些操作(Operation)对象,这些对象是计算节点。Tensor对象,则是表示在不同的操作(operation)间的数据节点。

2.6 tf.name_scope()和tf.variable_scope()的理解?

  • tf.name_scope(name, default_name=None, values=None) 主要结合 tf.Variable() 来使用,方便参数命名管理。

  • tf.variable_scope() 主要结合 tf.get_variable() 来使用,实现 变量共享。 先通过tf.variable_scope生成一个上下文管理器,并指明需求的变量在这个上下文管理器中,就可以直接通过tf.get_variable获取已经生成的变量。

我觉得这个相当于指定一个命名空间。

#通过tf.variable_scope函数控制tf.get_variable函数来获取以及创建过的变量  
with tf.variable_scope("ttf"):#ttf的命名空间  
        v=tf.get_variable("v",[1],initializer=tf.constant_initializer(1.0))  #在ttf的命名空间内创建名字为v的变量 

在上下文管理器中已经生成一个v的变量,若想通过tf.get_variable函数获取其变量,则可以通过reuse参数的设定为True来获取, 重用。

with tf.variable_scope("ttf",reuse=True):  
      v1=tf.get_variable("v",[1])  
print(v==v1)   #输出为True  

2.7 tf.variable_scope() 和tf.get_variable()的理解?

  • tf.variable_scope()

  • tf.get_variable() tf.get_variable(name, shape=None, dtype=None, initializer=None, regularizer=None, trainable=True, collections=None, caching_device=None, partitioner=None, validate_shape=True, use_resource=None, custom_getter=None)

Gets an existing variable with these parameters or create a new one. 获取或者创建变量。

当tf.get_variable用于创建变量时,则与tf.Variable的功能基本相同。

#定义的基本等价  
v = tf.get_variable("v",shape=[1],initializer.constant_initializer(1.0))  
v = tf.Variable(tf.constant(1.0,shape=[1]),name="v")  
  • 相同点:通过两函数创建变量的过程基本一样,且tf.variable函数调用时提供的维度(shape)信息以及初始化方法(initializer)的参数和tf.Variable函数调用时提供的初始化过程中的参数基本类似。
  • 不同点:两函数指定变量名称的参数不同,对于tf.Variable函数,变量名称是一个可选的参数,通过name="v"的形式给出,而tf.get_variable函数,变量名称是一个必填的参数,它会根据变量名称去创建或者获取变量。

2.8 tf.global_variables_initializer() 什么时候使用?

使用tf.global_variables_initializer()函数初始化所有可变张量的状态。

2.9 学习中的知识点收获记录?

3. 实践任务

a、使 tf实现Logistic Regression算法(必做) 截止日期:11.18

b、使 a任务实现的算法,完成 “Kaggle泰坦尼克之灾”(链接https://www.kaggle.com/c/titanic)(选做)截止日期:11.25

第四周的作业都出来, 吓得一条, 赶紧把第二周的实践作业完成了。

# -*- coding: utf-8 -*-
import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import Series,DataFrame
from sklearn.model_selection import train_test_split
data_train = pd.read_csv("./input/train.csv", header=0)
data_train.columns
Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
       'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],
      dtype='object')

PassengerId => 乘客ID
Pclass => 乘客等级(1/2/3等舱位)
Name => 乘客姓名
Sex => 性别
Age => 年龄
SibSp => 堂兄弟/妹个数
Parch => 父母与小孩个数
Ticket => 船票信息
Fare => 票价
Cabin => 客舱
Embarked => 登船港口

data_train.Sex.value_counts()
male      577
female    314
Name: Sex, dtype: int64
# 计算平均年龄
mean_age = int(data_train["Age"].mean())
mean_age
29
data_train2 = data_train
#将年龄为空的记录 用平均年龄填充
data_train2.loc[(data_train2.Age.isnull()), 'Age' ] = mean_age
# 有舱位的数据用Yes填充, 没有的用No
def setCabinType(df):
    df.loc[ (df.Cabin.notnull()), 'Cabin' ] = "Yes"
    df.loc[ (df.Cabin.isnull()), 'Cabin' ] = "No"
    return df
data_train2 = setCabinType(data_train2)
data_train2.head(5)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 No S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 Yes C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 No S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 Yes S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 No S
#特征离散化
dummies_Sex = pd.get_dummies(data_train2['Sex'], prefix= 'Sex')
dummies_Pclass = pd.get_dummies(data_train2['Pclass'], prefix= 'Pclass')
dummies_Cabin = pd.get_dummies(data_train2['Cabin'], prefix= 'Cabin')
dummies_Embarked = pd.get_dummies(data_train2['Embarked'], prefix= 'Embarked')
df = pd.concat([data_train, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)
df.head(5)
PassengerId Survived Age SibSp Parch Fare Cabin_No Cabin_Yes Embarked_C Embarked_Q Embarked_S Sex_female Sex_male Pclass_1 Pclass_2 Pclass_3
0 1 0 22.0 1 0 7.2500 1 0 0 0 1 0 1 0 0 1
1 2 1 38.0 1 0 71.2833 0 1 1 0 0 1 0 1 0 0
2 3 1 26.0 0 0 7.9250 1 0 0 0 1 1 0 0 0 1
3 4 1 35.0 1 0 53.1000 0 1 0 0 1 1 0 1 0 0
4 5 0 35.0 0 0 8.0500 1 0 0 0 1 0 1 0 0 1
train_df = df.filter(regex='Survived|Age_.*|Sex_.*|Pclass_.*')
train_np = train_df.as_matrix()

label = train_np[:, 0]
label=label.reshape((891,1))
print(label.shape)
input= train_np[:, 1:]
print(input.shape)

(891, 1)
(891, 5)
learning_rate = 0.5
seed = 0;

X_train, X_val, y_train, y_val = train_test_split(
    input, label, test_size = 0.2, random_state = seed)

print(X_train.shape)
print(X_val.shape)
print(y_train.shape)
print(y_val.shape)

# 训练数据
X = tf.placeholder(tf.float32, shape=[None, 5], name='input')
y = tf.placeholder(tf.float32, shape=[None, 1], name='label')

 # 声明参数权重变量
W = tf.Variable(tf.random_normal([5, 1]), name='weights')
b = tf.Variable(tf.zeros([1]), name='bias')

 # softmax逻辑回归
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)
 # 计算交叉熵的平均值
cost = tf.reduce_mean(cross_entropy)
 # 使用SDG最小化代价cost函数
train_op = tf.train.GradientDescentOptimizer(0.5).minimize(cost)
 # 保存训练模型
saver = tf.train.Saver()
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for epoch in range(100):
        total_loss = 0.0
        for i in range(len(X_train)):
            feed = {X: [X_train[i]], y: [y_train[i]]}
            _, loss = sess.run([train_op, cost], feed_dict=feed)
            total_loss += loss
        if (epoch % 10 == 0):
            print('Epoch: %04d, total loss=%.9f' % (epoch + 1, total_loss))
    print('Training complete!')
    # 用验证集评估模型的准确率
    pred_val = sess.run(y_pred, feed_dict={X: X_val})
    correct = np.equal(np.argmax(pred_val, 1), np.argmax(y_val, 1))
    accuracy = np.mean(correct.astype(np.float32))
    print('accuracy on validation set:%.9f' % accuracy)
    
    saver.save(sess, "Model/model_ema.ckpt")
    sess.close()
    

(712, 5)
(179, 5)
(712, 1)
(179, 1)
Epoch: 0001, total loss=0.000000000
Epoch: 0011, total loss=0.000000000
Epoch: 0021, total loss=0.000000000
Epoch: 0031, total loss=0.000000000
Epoch: 0041, total loss=0.000000000
Epoch: 0051, total loss=0.000000000
Epoch: 0061, total loss=0.000000000
Epoch: 0071, total loss=0.000000000
Epoch: 0081, total loss=0.000000000
Epoch: 0091, total loss=0.000000000
Training complete!
accuracy on validation set:1.000000000

参考文献

http://blog.csdn.net/hsj1213522415/article/details/70674197?locationNum=9&fps=1 https://www.zhihu.com/question/29021768 https://zhuanlan.zhihu.com/p/25110450 https://www.zhihu.com/question/23765351 https://zh.wikipedia.org/wiki/Softmax函数 http://blog.csdn.net/sinat_32329183/article/details/77835677 http://blog.csdn.net/lanchunhui/article/details/61712830


【luxuriance19】TF学习笔记总结-week6暂时完结,不定期回补
#2

年底,事情都比较多,坚持就是胜利,熬过这段时间,会有更多收获