CNN模型搭建代码学习

CNN卷积网络搭建代码学习

1.Python中sys.argv[]用法
详细

DATA_DIR = sys.argv[1]#外部输入的第一个参数
CLASS_NUM = int(sys.argv[2])
TRAIN_ROUND = int(sys.argv[3])
#DATA_DIR = '/root/data/withip/10class/BenignFlowAllLayers'
#CLASS_NUM = 10
#TRAIN_ROUND = 40000

Sys.argv[ ]其实就是一个列表,里边的项为用户输入的参数,关键就是要明白这参数是从程序外部输入的,而非代码本身的什么地方,要想看到它的效果就应该将程序保存了,从外部来运行程序并给出参数。

2.字典用法
dict()用法

dict_2class = {0:'Benign',1:'Malware'}
dict_10class_benign = {0:'BitTorrent',1:'Facetime',2:'FTP',3:'Gmail',4:'MySQL',5:'Outlook',6:'Skype',7:'SMB',8:'Weibo',9:'WorldOfWarcraft'}
dict_10class_malware = {0:'Cridex',1:'Geodo',2:'Htbot',3:'Miuref',4:'Neris',5:'Nsis-ay',6:'Shifu',7:'Tinba',8:'Virut',9:'Zeus'}
dict_20class = {0:'BitTorrent',1:'Facetime',2:'FTP',3:'Gmail',4:'MySQL',5:'Outlook',6:'Skype',7:'SMB',8:'Weibo',9:'WorldOfWarcraft',10:'Cridex',11:'Geodo',12:'Htbot',13:'Miuref',14:'Neris',15:'Nsis-ay',16:'Shifu',17:'Tinba',18:'Virut',19:'Zeus'}
dict = {}

3.路径文件名分割os.path.split()[]
split()和os.path.split()用法

folder = os.path.split(DATA_DIR)[1]# 分割取文件名

os.path.split(‘PATH’)

1.PATH指一个文件的全路径作为参数:

2.如果给出的是一个目录和文件名,则输出路径和文件名

3.如果给出的是一个目录名,则输出路径和为空文件名
os.path.split()[1]是取分割后list的第二项,即文件名

4.tf.InteractiveSession()
tf.Session()和tf.InteractiveSession()区别

sess = tf.InteractiveSession()

总结:tf.InteractiveSession()默认自己就是用户要操作的session,而tf.Session()没有这个默认,因此用eval()启动计算时需要指明session。

5.tf.app.flag使用

Tensorflow中tf.app.flags的作用及使用方法

最详细的举例

Tensorflow使用flags定义命令行参数详解

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('data_dir', DATA_DIR, 'Directory for storing data')

6.mnist数据集下载?

mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)

tf实例数据下载及研究

**

7.find a element in a list

**

def find_element_in_list(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return -1

详细实例

找的是该元素在列表中的位置

List of strings*

list_of_elems = ['Hello', 'Ok', 'is', 'Ok', 'test', 'this', 'is', 'a', 'test', 'Ok']

Now let’s find the index of the first occurrence of item ‘Ok‘ in the list,
elem = ‘Ok’

Find index position of first occurrence of ‘Ok’ in the list

index_pos = list_of_elems.index(elem)
print(f'First Index of element "{elem}" in the list : ', index_pos)

Output
First Index of element “Ok” in the list : 1

8.tf.truncated_normal

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

tf.truncated_nomal用法
产生截断正态分布随机数
权值初始化讲解

如果该函数中的初始化函数 tf.truncated_normal(shape, stddev=0.1) 不设置参数 stddev 的话,训练精度最多只能到 20% 左右,即使调整优化器的学习了到很大,训练精度也不会超过 20%
参数 stddev 用于设置正太分布被截断前的标准差,设置了 stddev=0.1 后,训练精度就达到达到 99.2% 以上

9.创建常量

tf.constant详细举例

def bias_variable(shape):
    initial = tf.constant(0.1, shape = shape)
    return tf.Variable(initial)

权重在初始化时应该加入少量的噪声(偏差stddev=0.1)来打破对称性以及避免0梯度。由于我们使用的是ReLU神经元,因此比较好的做法是用一个较小的正数来初始化偏置项,以避免神经元节点输出恒为0的问题(dead neurons)。为了不在建立模型的时候反复做初始化操作,我们定义两个函数用于初始化。
tensorflow笔记(可用作材料说明!)神经网络mnist讲解

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1) 
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

mnist讲解神经网络(较详细

10卷积层 池化层

def conv2d(x, W):
    # stride [1, x_movement, y_movement, 1]
    # Must have strides[0] = strides[3] = 1
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
    # stride [1, x_movement, y_movement, 1]
    #ksize  [1,pool_op_length,pool_op_width,1]
    # Must have ksize[0] = ksize[3] = 1
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

全代码讲解 各部分都详细

conv2d函数的输入参数是要进行卷积的图片x和卷积核W,函数内部strides是卷积核步长的设定,上面已进行标注,x轴,y轴都是每隔一个像素移动的,步长都为1,padding是填充的意思,这里是SAME,意思是卷积后的图片与原图片一样,有填充。
max_pool_2X2函数的输入参数是卷积后的图片x,ksize是池化算子,由于是2x2max_pool,所以长度和宽度都为2,x轴和y轴的步长都为2,有填充。

11占位符tf.placefolder()

x = tf.placeholder("float", [None, 784])  #28*28像素  None第一维度,任意大小
y_ = tf.placeholder("float", [None, CLASS_NUM])

函数可以理解为形参,用于定义过程,在执行的时候再赋具体的值

函数解释1
解释2
参数解释3

其中784是单个扁平28乘28像素MNIST图像的维数,无表示第一个维度,对应于批量大小,可以任何大小。

12. tf.reshape

x_image = tf.reshape(x, [-1, 28, 28, 1])

这里是将一组图像矩阵x重建为新的矩阵,该新矩阵的维数为(a,28,28,1),其中-1表示a由实际情况来定。
例如,x是一组图像的矩阵(假设是50张,大小为56×56),则执行x_image = tf.reshape(x, [-1, 28, 28, 1])可以计算a=50×56×56/28/28/1=200。即x_image的维数为(200,28,28,1)。

参考

13.卷积函数(解释为什么输入是4维,需要reshape变化维度)

TensorFlow卷积函数tf.nn.conv2d

指需要做卷积的输入图像(tensor),具有[batch,in_height,in_width,in_channels]这样的4维shape,分别是图片数量、图片高度、图片宽度、图片通道数,数据类型为float32或float64。

tf.nn.conv2d(
    input,
    filter,
    strides,
    padding,
    use_cudnn_on_gpu=True,
    data_format='NHWC',
    dilations=[1, 1, 1, 1],
    name=None
)

Returns:
A Tensor. 

14.第一层卷积网络

# first convolutinal layer
w_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

x_image = tf.reshape(x, [-1, 28, 28, 1])# 变维度4维输入

h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

卷积核的大小是5x5的,由于输入size1,输出32,可见有32个不同的卷积核,然后将W_conv1与x_image送入conv2d函数后加入偏差,最后外围加上RELU函数,RELU函数是相比其他函数(sigmiod)好很多,使用它,迭代速度会很快,因为它的大于0的导数恒等于1,而sigmiod的导数有可能会很小,趋近于0,我们在进行反向传播迭代参数更新时,如果这个导数太小,参数的更新就会很慢。

relu: Tensorflow中tf.nn.relu()函数的理解

卷积函数一个通道一个输出:

import tensorflow as tf
input = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 1]))
filter = tf.Variable(tf.constant([-1.0, 0, 0, -1], shape=[2, 2, 1, 1]))
op = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')

init = tf.global_variables_initializer()
with tf.Session() as sess:
  sess.run(init)
  print("op:\n",sess.run(op))

filter:
相当于CNN中的卷积核,它是一个tensor,shape是[filter_height,filter_width,in_channels,out_channels]:滤波器高度、宽度、图像通道数、滤波器个数,数据类型和input相同。

本题中将各参数分开定义,再赋初始值送入卷积函数加偏置加relu

# weight initialization权值初始化
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1) #打破对称性和零梯度 shape卷积核长度
    return tf.Variable(initial)

def bias_variable(shape):#偏执置矩阵初始化
    initial = tf.constant(0.1, shape = shape)     # print(tf.Variable(initial).eval())
    return tf.Variable(initial)

# convolution
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
    #pooling
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
再赋值带入计算
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

x_image = tf.reshape(x, [-1, 28, 28, 1])# 变维度4维输入

h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

15.第二层卷积网络

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) 

特征提取出来了,我们开始用全连通层进行预测,在建立之前,我们需要对h_pool2进行维度处理,因为神经网络的输入并不能是4维张量。上面将4维张量,变为2维张量,第一维是样本数,第二维是输入特征,可见输入神经元的个数是7764=3136

# densely connected layer
w_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
#将4维张量,变为2维张量,第一维是样本数,第二维是输入特征,可见输入神经元的个数是7*7*64=3136
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)

类似第一层的卷积网络

16.输出层

# dropout
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

keep_prob:含具体事例
dropout用法

tf.nn.dropout是TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层。
Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了。

f.nn.dropout(x, keep_prob, noise_shape=None, seed=None,name=None)
上面方法中常用的是前两个参数:
第一个参数x:指输入
第二个参数keep_prob: 设置神经元被选中的概率,在初始化时keep_prob是一个占位符, keep_prob = tf.placeholder(tf.float32) 。tensorflow在run时设置keep_prob具体的值,例如keep_prob: 0.5

使用举例:

1、dropout必须设置概率keep_prob,并且keep_prob也是一个占位符,跟输入是一样的

1. keep_prob = tf.placeholder(tf.float32)  

2、train的时候才是dropout起作用的时候,train和test的时候不应该让dropout起作用

1. sess.run(train_step, feed_dict={xs: X_train, ys: y_train, keep_prob: 0.5})  
1. train_result = sess.run(merged, feed_dict={xs: X_train, ys: y_train, keep_prob: 1})  
2. test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test, keep_prob: 1})  

17.softmax层

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2)#每个情况的概率

softmax详解(可引至材料)

tf.nn.softmax(
    logits,
    axis=None,
    name=None,
    dim=None
)

①作用:softmax函数的作用就是归一化。
②输入: 全连接层(往往是模型的最后一层)的值,一般代码中叫做logits
③输出: 归一化的值,含义是属于该位置的概率,一般代码叫做probs。
例如输入[0.4,0.1,0.2,0.3],那么这个样本最可能属于第0个位置,也就是第0类。这是由于logits的维度大小就设定的是任务的类别,所以第0个位置就代表第0类。softmax函数的输出不改变维度的大小。
④用途:如果做单分类问题,那么输出的值就取top1(最大,argmax);如果做多(N)分类问题,那么输出的值就取topN

18. 全连接层2(一共两个全连接层)

整个全连接层代码

# densely connected layer
w_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
#将4维张量,变为2维张量,第一维是样本数,第二维是输入特征,可见输入神经元的个数是7*7*64=3136
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)  #全连接层(不卷积conv2d),直接相乘

# dropout
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)  #防止过拟合

# readout layer
w_fc2 = weight_variable([1024, CLASS_NUM])  #全连接层2
b_fc2 = bias_variable([CLASS_NUM])

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2)#每个情况的概率

然后再加一个全连通层,进行1024神经元到10个神经元的映射,最后加一个softmax层,得出每种情况的概率

关于tf.matmul:tf.matmul() 和tf.multiply() 的区别

两矩阵相乘,不是卷积层,所以不送进conv2d里

19.交叉熵

解释

公式:交叉熵 和 softmax 公式及 python 实现

cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))  #交叉熵函数公式
train_step = tf.train.GradientDescentOptimizer(1e-4).minimize(cross_entropy)  #优化器的选择

20.优化器的选择(可单独列出来放材料里)

cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),reduction_indices=[1]))       # loss
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))  #交叉熵函数公式
train_step = tf.train.GradientDescentOptimizer(1e-4).minimize(cross_entropy)  #优化器的选择

AdamOptimizer优化器,由于这个计算量很大;
用GradientDescentOptimizer优化器下降速度太慢

21.

# define var&op of training&testing
actual_label = tf.argmax(y_, 1)  #标签 行最大索引值
label,idx,count = tf.unique_with_counts(actual_label)

cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))  #交叉熵函数公式
train_step = tf.train.GradientDescentOptimizer(1e-4).minimize(cross_entropy)  #优化器的选择

predict_label = tf.argmax(y_conv, 1)
label_p,idx_p,count_p = tf.unique_with_counts(predict_label)

correct_prediction = tf.equal(predict_label, actual_label)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
correct_label=tf.boolean_mask(actual_label,correct_prediction)
label_c,idx_c,count_c=tf.unique_with_counts(correct_label)

tf.argmax()解析

tf.unique_with_count()返回值

tf.equal()函数用法及解析

import tensorflow as tf
a = [[1,2,3],[4,5,6]]
b = [[1,0,3],[1,5,1]]
with tf.Session() as sess:
   print(sess.run(tf.equal(a,b)))

输出:

[[ True False  True]
[False  True False]]

你可能感兴趣的:(python学习,深度学习,tensorflow)