模型里没有参数被初始化为0 ,学习率从10的-5次方试到了0.1,输入数据都已经被归一化为了0-1之间,模型是改过的vgg16,有四个输出,使用了vgg16的预训练模型来初始化参数,输出中间结果也没有nan或者inf值。是不是不能自定义损失函数呢?但输出中间梯度发现并不是0,非常奇怪。
train.py的部分代码
def train():
x = tf.placeholder(tf.float32, [None, 182, 182, 2], name = 'image_input')
y_ = tf.placeholder(tf.float32, [None, 8], name='label_input')
global_step = tf.Variable(0, trainable=False)
learning_rate = tf.train.exponential_decay(learning_rate=0.0001,decay_rate=0.9, global_step=TRAINING_STEPS, decay_steps=50,staircase=True)
# 读取图片数据,pos是标签为1的图,neg是标签为0的图
pos, neg = get_data.get_image(img_path)
#输入标签固定,输入数据每个batch前4张放pos,后4张放neg
label_batch = np.reshape(np.array([1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]),[1, 8])
vgg = vgg16.Vgg16()
vgg.build(x)
#loss函数的定义在后面
loss = vgg.side_loss( y_,vgg.output1, vgg.output2, vgg.output3, vgg.output4)
train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss, global_step=global_step)
init_op = tf.global_variables_initializer()
saver = tf.train.Saver()
with tf.device('/gpu:0'):
with tf.Session() as sess:
sess.run(init_op)
for i in range(TRAINING_STEPS):
#在train.py的其他部分定义了batch_size= 4
start = i * batch_size
end = start + batch_size
#制作输入数据,前4个是标签为1的图,后4个是标签为0的图
image_list = []
image_list.append(pos[start:end])
image_list.append(neg[start:end])
image_batch = np.reshape(np.array(image_list),[-1,182,182,2])
_,loss_val,step = sess.run([train_step,loss,global_step], feed_dict={x: image_batch,y_:label_batch})
if i % 50 == 0:
print("the step is %d,loss is %f" % (step, loss_val))
if loss_val < min_loss:
min_loss = loss_val
saver.save(sess, 'ckpt/vgg.ckpt', global_step=2000)
Loss 函数的定义
**loss函数的定义(写在了Vgg16类里)**
class Vgg16:
#a,b,c,d都是vgg模型里的输出,是多输出模型
def side_loss(self,yi,a,b,c,d):
self.loss1 = self.f_indicator(yi, a)
self.loss2 = self.f_indicator(yi, b)
self.loss3 = self.f_indicator(yi, c)
self.loss_fuse = self.f_indicator(yi, d)
self.loss_side = self.loss1 + self.loss2 + self.loss3 + self.loss_fuse
res_loss = tf.reduce_sum(self.loss_side)
return res_loss
#损失函数的定义,标签为0时为log(1-yj),标签为1时为log(yj)
def f_indicator(self,yi,yj):
b = tf.where(yj>=1,yj*50,tf.abs(tf.log(tf.abs(1 - yj))))
res=tf.where(tf.equal(yi , 0.0), b,tf.abs(tf.log(tf.clip_by_value(yj, 1e-8, float("inf")))))
return res