方式1使用轻量级库TF-Slim
import tensorflow.contrib.slim as slim
1.使用slim创建变量
#常规变量,step那种
weights = slim.variable('weights',
shape=[384,12,12,3].
#方差为0.1
initializer=tf.truncated_normal_initializer(stddev=0.1),
#l2正则
regularizer=slim.l2_regularizer(0.05),
device='/cpu:0')
#模型变量
weights = slim.model_variable('weights',
shape=[10, 10, 3 , 3],
initializer=tf.truncated_normal_initializer(stddev=0.1),
regularizer=slim.l2_regularizer(0.05),
device='/CPU:0')
#让TF-Slim管理我们自定义的变量
slim.add_model_variable(weights)
2.使用slim搭建网络
#这里对比一些常规的搭建与使用slim搭建的不同
#使用常规搭建
with tf.name_scope('conv1') as scope:
kernel = tf.Variable(tf.truncated_normal([3,3,64,128],dtype=float32,stddev=1e-1),name='weights')
conv = tf.nn.conv2d(input,kernel,[1,1,1,1],padding='SAME')
bias = tf.Variable(tf.constant(0.0,shape=[128],dtype=float32),trainable='True',name='bias')
bias = tf.nn.bias_add(conv,bias)
conv1 = tf.nn.relu(bias,name=scope)
#使用slim
net = slim.conv2d(input,128,[3,3],scope='conv1')
#多层堆叠
net1 = slim.conv2d(input,128,[3,3],scope='conv1')
net2 = slim.conv2d(net1,256,[2,2],scope='conv2')
net3 = slim.conv2d(net2,512,[1,1],scope='conv3')
x = slim.fully_connected(x,32,scope='fc1')
x = slim.fully_connected(x,64,scope='fc2')
x = slim.fully_connected(x,128,scope='fc3')
#这里说一些slim.arg_scope(),我们可以这么理解,这个函数是
#用来重写或者说是定义一些conv2d这种函数中一些参数的,为什么要
#这么做,因为搭建神经网络的时候,很多层的定义,比如卷积大小,或
#者激活函数这些是固定的,因此使用这个函数直接全部定义,减少了代码量。
with slim.arg_scope([slim.conv2d], padding='SAME',
weights_initializer=tf.truncated_normal_initializer(stddev=0.01)
weights_regularizer=slim.l2_regularizer(0.0005)):
net = slim.conv2d(inputs, 64, [11, 11], scope='conv1')
net = slim.conv2d(net, 128, [11, 11], padding='VALID', scope='conv2')
net = slim.conv2d(net, 256, [11, 11], scope='conv3')
##举例搭建vgg16
def vgg16(inputs):
with slim.arg_scope([slim.conv2d,slim.slim.fully_connected],
activation_fn = tf.nn.relu,
weights_initializer=tf.truncated_normal_initializer(0.0, 0.01),
weights_regularizer=slim.l2_regularizer(0.0005)):
net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1')
net = slim.max_pool2d(net, [2, 2], scope='pool1')
net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2')
net = slim.max_pool2d(net, [2, 2], scope='pool2')
net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
net = slim.max_pool2d(net, [2, 2], scope='pool3')
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv4')
net = slim.max_pool2d(net, [2, 2], scope='pool4')
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv5')
net = slim.max_pool2d(net, [2, 2], scope='pool5')
net = slim.fully_connected(net, 4096, scope='fc6')
net = slim.dropout(net, 0.5, scope='dropout6')
net = slim.fully_connected(net, 4096, scope='fc7')
net = slim.dropout(net, 0.5, scope='dropout7')
net = slim.fully_connected(net, 1000, activation_fn=None, scope='fc8')
return net
3.定义损失
对于多任务学习模型,以MTCNN为例,在每一层时都会有好几个损失同时训练
那么这些损失如何一起反向传播进行训练,而不是看上去是多任务,其实每次都是
一个任务一个任务的训练。
因此可以使用silm losses包对所有的loss进行管理,说白了就是把所有的自定义的loss
添加到silm losses环境里面,然后sees.run(train_op)
1.对于直接调用的slim.losses.softmax_cross_entropy()这类的,
其本身就是输入slim losses环境里面的因此可以直接相加,然后sess.run(train_op)
2.对于需要自己定义的,损失,那么就需要把自己定义的损失加到slim losses环境中
然后sees.run(train_op)
eg: 直接调用slim losses中的损失包
classification_loss = slim.losses.softmax_cross_entropy(cls_pre,cls_target)
sum_of_square_loss = slim.losses.sum_of_square_loss(cls_pre,cls_targt)
求多任务损失的和,下面这两种方式结果都一样,注意add_regularization_losses=False 这个是没有加自定义损失
train_op = classification_loss + sum_of_square_loss
train_op = slim.losses.get_total_loss(add_regularization_losses=False)
eg:自定义损失
sum_of_square_loss = slim.losses.sum_of_square_loss(cls_pre ,cls_target)
my_loss = tf.square(cls_pre - cls_target)
把my_loss 先加到slim losses中
slim.losses.add_loss(my_loss)
#把所有调用了的slim losses中的损失加到一起
regu = tf.add_n(slim.losses.get_regularization_losses())
参考文章:https://blog.csdn.net/guvcolie/article/details/77686555