当前位置:   article > 正文

针对keras模型多输出或多损失方法使用_keras 自定义损失层计算多输出损失

keras 自定义损失层计算多输出损失

有些模型存在多个输出在计算loss的情况,其中比较典型的如hed边缘检测网络,该网络具体介绍可以看之前的博客;hed网络有多个输出,写法如下;

实例一

  1. def hed():
  2. # Input
  3. img_input = Input(shape=(480,480,3), name='input')
  4. # Block 1
  5. x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)
  6. x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
  7. b1= side_branch(x, 1) # 480 480 1
  8. x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block1_pool')(x) # 240 240 64
  9. # Block 2
  10. x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
  11. x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
  12. b2= side_branch(x, 2) # 480 480 1
  13. x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block2_pool')(x) # 120 120 128
  14. # Block 3
  15. x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
  16. x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
  17. x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
  18. b3= side_branch(x, 4) # 480 480 1
  19. x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block3_pool')(x) # 60 60 256
  20. # Block 4
  21. x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
  22. x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
  23. x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
  24. b4= side_branch(x, 8) # 480 480 1
  25. x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block4_pool')(x) # 30 30 512
  26. # Block 5
  27. x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
  28. x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
  29. x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x) # 30 30 512
  30. b5= side_branch(x, 16) # 480 480 1
  31. # fuse
  32. fuse = Concatenate(axis=-1)([b1, b2, b3, b4, b5])
  33. fuse = Conv2D(1, (1,1), padding='same', use_bias=False, activation=None)(fuse) # 480 480 1
  34. # outputs
  35. o1 = Activation('sigmoid', name='o1')(b1)
  36. o2 = Activation('sigmoid', name='o2')(b2)
  37. o3 = Activation('sigmoid', name='o3')(b3)
  38. o4 = Activation('sigmoid', name='o4')(b4)
  39. o5 = Activation('sigmoid', name='o5')(b5)
  40. ofuse = Activation('sigmoid', name='ofuse')(fuse)
  41. # model
  42. model = Model(inputs=[img_input], outputs=[o1, o2, o3, o4, o5, ofuse])
  43. filepath = './models/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
  44. # load_weights_from_hdf5_group_by_name(model, filepath)
  45. adam = Adam(lr = 1e-4, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0001)
  46. model.compile(optimizer= adam,
  47. loss={'o1': cross_entropy_balanced,
  48. 'o2': cross_entropy_balanced,
  49. 'o3': cross_entropy_balanced,
  50. 'o4': cross_entropy_balanced,
  51. 'o5': cross_entropy_balanced,
  52. 'ofuse': cross_entropy_balanced,
  53. },
  54. metrics={'ofuse': ofuse_pixel_error})
  55. return model

实例二

同时该博客也提供了类似方法https://blog.csdn.net/u012938704/article/details/79904173,搬运一下如下;

部分代码

  1. # create the base pre-trained model
  2. input_tensor = Input(shape=(299, 299, 3))
  3. base_model = Xception(include_top=True, weights='imagenet', input_tensor=None, input_shape=None)
  4. plot_model(base_model, to_file='xception_model.png')
  5. base_model.layers.pop()
  6. base_model.outputs = [base_model.layers[-1].output]
  7. base_model.layers[-1].outbound_nodes = []
  8. base_model.output_layers = [base_model.layers[-1]]
  9. feature = base_model
  10. img1 = Input(shape=(299, 299, 3), name='img_1')
  11. img2 = Input(shape=(299, 299, 3), name='img_2')
  12. feature1 = feature(img1)
  13. feature2 = feature(img2)
  14. # Three loss functions
  15. category_predict1 = Dense(100, activation='softmax', name='ctg_out_1')(
  16. Dropout(0.5)(feature1)
  17. )
  18. category_predict2 = Dense(100, activation='softmax', name='ctg_out_2')(
  19. Dropout(0.5)(feature2)
  20. )
  21. dis = Lambda(eucl_dist, name='square')([feature1, feature2])
  22. judge = Dense(2, activation='softmax', name='bin_out')(dis)
  23. model = Model(inputs=[img1, img2], outputs=[category_predict1, category_predict2, judge])
  24. model.compile(optimizer=SGD(lr=0.0001, momentum=0.9),
  25. loss={
  26. 'ctg_out_1': 'categorical_crossentropy',
  27. 'ctg_out_2': 'categorical_crossentropy',
  28. 'bin_out': 'categorical_crossentropy'},
  29. loss_weights={
  30. 'ctg_out_1': 1.,
  31. 'ctg_out_2': 1.,
  32. 'bin_out': 0.5
  33. },
  34. metrics=['accuracy'])

完整代码:https://github.com/ahangchen/keras-dogs/blob/master/single/single_model.py

  1. import os
  2. import numpy as np
  3. os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" # see issue #152
  4. os.environ["CUDA_VISIBLE_DEVICES"] = "1"
  5. from keras import Input
  6. from keras.applications import Xception, InceptionV3
  7. from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
  8. from keras.layers import Dense, Dropout, concatenate, maximum
  9. from keras.models import Model, load_model
  10. from keras.optimizers import SGD
  11. from keras.preprocessing.image import ImageDataGenerator
  12. from keras.utils import plot_model
  13. train_datagen = ImageDataGenerator(
  14. rescale=1. / 255,
  15. shear_range=0.2,
  16. width_shift_range=0.4,
  17. height_shift_range=0.4,
  18. rotation_range=90,
  19. zoom_range=0.7,
  20. horizontal_flip=True,
  21. vertical_flip=True)
  22. test_datagen = ImageDataGenerator(rescale=1. / 255)
  23. batch_size = 48
  24. train_generator = train_datagen.flow_from_directory(
  25. '/hdd/cwh/dog_keras_train',
  26. # '/home/cwh/coding/data/cwh/test1',
  27. target_size=(299, 299),
  28. # batch_size=1,
  29. batch_size=batch_size,
  30. class_mode='categorical')
  31. validation_generator = test_datagen.flow_from_directory(
  32. '/hdd/cwh/dog_keras_valid',
  33. # '/home/cwh/coding/data/cwh/test1',
  34. target_size=(299, 299),
  35. # batch_size=1,
  36. batch_size=batch_size,
  37. class_mode='categorical')
  38. def triple_generator(generator):
  39. while True:
  40. x, y = generator.next()
  41. yield x, [y, y, y, y]
  42. early_stopping = EarlyStopping(monitor='val_loss', patience=3)
  43. auto_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=0, mode='auto', epsilon=0.0001,
  44. cooldown=0, min_lr=0)
  45. if os.path.exists('dog_single_xception.h5'):
  46. model = load_model('dog_single_xception.h5')
  47. else:
  48. # create the base pre-trained model
  49. input_tensor = Input(shape=(299, 299, 3))
  50. base_model1 = Xception(include_top=True, weights='imagenet', input_tensor=None, input_shape=None)
  51. base_model1 = Model(inputs=[base_model1.input], outputs=[base_model1.get_layer('avg_pool').output], name='xception')
  52. base_model2 = InceptionV3(include_top=True, weights='imagenet', input_tensor=None, input_shape=None)
  53. base_model2 = Model(inputs=[base_model2.input], outputs=[base_model2.get_layer('avg_pool').output],
  54. name='inceptionv3')
  55. img1 = Input(shape=(299, 299, 3), name='img_1')
  56. feature1 = base_model1(img1)
  57. feature2 = base_model2(img1)
  58. # let's add a fully-connected layer
  59. category_predict1 = Dense(100, activation='softmax', name='ctg_out_1')(
  60. Dropout(0.5)(
  61. feature1
  62. )
  63. )
  64. category_predict2 = Dense(100, activation='softmax', name='ctg_out_2')(
  65. Dropout(0.5)(
  66. feature2
  67. )
  68. )
  69. category_predict = Dense(100, activation='softmax', name='ctg_out')(
  70. concatenate([feature1, feature2])
  71. )
  72. max_category_predict = maximum([category_predict1, category_predict2])
  73. model = Model(inputs=[img1], outputs=[category_predict1, category_predict2, category_predict, max_category_predict])
  74. # model.save('dog_xception.h5')
  75. plot_model(model, to_file='single_model.png')
  76. # first: train only the top layers (which were randomly initialized)
  77. # i.e. freeze all convolutional InceptionV3 layers
  78. for layer in base_model1.layers:
  79. layer.trainable = False
  80. for layer in base_model2.layers:
  81. layer.trainable = False
  82. # compile the model (should be done *after* setting layers to non-trainable)
  83. model.compile(optimizer='nadam',
  84. loss={
  85. 'ctg_out_1': 'categorical_crossentropy',
  86. 'ctg_out_2': 'categorical_crossentropy',
  87. 'ctg_out': 'categorical_crossentropy',
  88. 'maximum_1': 'categorical_crossentropy'
  89. },
  90. metrics=['accuracy'])
  91. # model = make_parallel(model, 3)
  92. # train the model on the new data for a few epochs
  93. model.fit_generator(triple_generator(train_generator),
  94. steps_per_epoch=16500 / batch_size + 1,
  95. epochs=30,
  96. validation_data=triple_generator(validation_generator),
  97. validation_steps=1800 / batch_size + 1,
  98. callbacks=[early_stopping, auto_lr])
  99. model.save('dog_single_xception.h5')
  100. # at this point, the top layers are well trained and we can start fine-tuning
  101. # convolutional layers from inception V3. We will freeze the bottom N layers
  102. # and train the remaining top layers.
  103. # let's visualize layer names and layer indices to see how many layers
  104. # we should freeze:
  105. for i, layer in enumerate(model.layers):
  106. print(i, layer.name)
  107. # we chose to train the top 2 inception blocks, i.e. we will freeze
  108. # the first 172 layers and unfreeze the rest:
  109. cur_base_model = model.layers[1]
  110. for layer in cur_base_model.layers[:105]:
  111. layer.trainable = False
  112. for layer in cur_base_model.layers[105:]:
  113. layer.trainable = True
  114. cur_base_model = model.layers[2]
  115. for layer in cur_base_model.layers[:262]:
  116. layer.trainable = False
  117. for layer in cur_base_model.layers[262:]:
  118. layer.trainable = True
  119. # we need to recompile the model for these modifications to take effect
  120. # we use SGD with a low learning rate
  121. model.compile(optimizer=SGD(lr=0.0001, momentum=0.9),
  122. loss={
  123. 'ctg_out_1': 'categorical_crossentropy',
  124. 'ctg_out_2': 'categorical_crossentropy',
  125. 'ctg_out': 'categorical_crossentropy',
  126. 'maximum_1': 'categorical_crossentropy'
  127. },
  128. metrics=['accuracy'])
  129. batch_size = batch_size * 3 / 4
  130. train_generator = test_datagen.flow_from_directory(
  131. '/hdd/cwh/dog_keras_train',
  132. # '/home/cwh/coding/data/cwh/test1',
  133. target_size=(299, 299),
  134. # batch_size=1,
  135. batch_size=batch_size,
  136. class_mode='categorical')
  137. validation_generator = test_datagen.flow_from_directory(
  138. '/hdd/cwh/dog_keras_valid',
  139. # '/home/cwh/coding/data/cwh/test1',
  140. target_size=(299, 299),
  141. # batch_size=1,
  142. batch_size=batch_size,
  143. class_mode='categorical')
  144. # we train our model again (this time fine-tuning the top 2 inception blocks
  145. # alongside the top Dense layers
  146. save_model = ModelCheckpoint('xception-tuned{epoch:02d}-{val_ctg_out_acc:.2f}.h5')
  147. model.fit_generator(triple_generator(train_generator),
  148. steps_per_epoch=16500 / batch_size + 1,
  149. epochs=30,
  150. validation_data=triple_generator(validation_generator),
  151. validation_steps=1800 / batch_size + 1,
  152. callbacks=[early_stopping, auto_lr, save_model]) # otherwise the generator would loop indefinitely
  153. model.save('dog_single_xception_tuned.h5')

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/133240
推荐阅读
相关标签
  

闽ICP备14008679号