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实例数据下载及研究
**
**
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% 以上
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.
# 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)
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)
类似第一层的卷积网络
# 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})
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
(整个全连接层代码)
# 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里
解释
公式:交叉熵 和 softmax 公式及 python 实现
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv)) #交叉熵函数公式
train_step = tf.train.GradientDescentOptimizer(1e-4).minimize(cross_entropy) #优化器的选择
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优化器下降速度太慢
# 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]]