嗨,我正在尝试使用Keras编写YoloV1,但是当我使用Tensorflow操作定义损失函数时:
import os
import pdb
import numpy as np
import xml.etree.ElementTree as ET
import cv2
from shutil import copyfile
from pprint import pprint
from math import sqrt
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.applications.vgg16 import preprocess_input
from tensorflow.keras.applications.vgg16 import decode_predictions
from tensorflow.keras import layers
from tensorflow.keras import Input
from tensorflow.keras.models import Model, load_model
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.layers import Dropout
from tensorflow.keras import regularizers
import tensorflow.keras.backend as K
import tensorflow as tf
def yolov1_loss(y_true, y_pred):
"Custom loss function for YoloV1"
img_size = 448
backbone_img_size = 224
grid_num_per_axis = 2
grid_num = grid_num_per_axis**2
cls_list = ['aeroplane', 'bicycle', 'bird']
n_cls = len(cls_list)
num_bbox_per_grid = 2
batch_size = 1
prob_loss = tf.Variable(0.0)
prob_true = y_true[:, :, :, 5*num_bbox_per_grid:]
prob_pred = y_pred[:, :, :, 5*num_bbox_per_grid:]
obj_in_true = y_true[:, :, :, 0]
diff = tf.math.subtract(prob_true, prob_pred)
squared_sum_diff = tf.math.reduce_sum(tf.math.square(diff), axis=3)
# squared_sum_diff_obj_in_true = tf.math.multiply(obj_in_true, squared_sum_diff)
# prob_loss.assign(tf.math.reduce_sum(squared_sum_diff_obj_in_true))
prob_loss.assign(tf.math.reduce_sum(squared_sum_diff))
# diff = prob_true - prob_pred
# squared_sum_diff = K.sum(K.square(diff), axis=3)
# squared_sum_diff_obj_in_true = obj_in_true * squared_sum_diff
# prob_loss = K.sum(squared_sum_diff_obj_in_true,axis=[0,1,2])
# pdb.set_trace()
return prob_loss
def main():
cls_list = ['aeroplane', 'bicycle', 'bird']
y_true = tf.constant(
[[[[1, 0.3, 0.4, 0.2, 0.5, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0.1, 0.6, 0.3, 0.2, 0, 0, 0, 0, 0, 0, 1, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0.6, 0.5, 0.2, 0.1, 0, 0, 0, 0, 0, 0, 0, 1]] ]]
)
y_pred = tf.constant(
[[[[0.8, 0.4, 0.3, 0.15, 0.6, 0, 0, 0, 0, 0, 0.8, 0.1, 0.1], [0.7, 0.1, 0.6, 0.3, 0.2, 0, 0, 0, 0, 0, 0.5, 0.4, 0.1]],
[[0.4, 0.2, 0.01, 0.01, 0.04, 0, 0, 0, 0, 0, 0.3, 0.3, 0.4], [0.6, 0.4, 0.3, 0.4, 0.2, 0, 0, 0, 0, 0, 0.3, 0.3, 0.4]]]]
)
loss = yolov1_loss(y_true, y_pred)
base_model = VGG16(
input_shape=(224,224,3),
include_top=False,
weights='imagenet')
img_input = Input(shape=(448,448,3))
arch = layers.Conv2D(64, 3, padding='same', activation='relu') (img_input)
arch = layers.MaxPooling2D() (arch)
for i, layer in enumerate(base_model.layers[2:]):
arch = layer(arch)
arch = layers.Flatten() (arch)
arch = layers.Dense(4096, activation='relu') (arch)
arch = layers.Dense((2**2)*(2*5 + 3)) (arch)
arch = layers.Reshape(
(2, 2, 2*5 + 3)) (arch)
model = Model(inputs=img_input, outputs=arch)
model.summary()
model.compile(
optimizer='rmsprop',
loss=yolov1_loss)
X_train = np.random.rand(5, 448, 448, 3)
y_train = np.array(
[
[[[1, 0.3, 0.4, 0.2, 0.5, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0.1, 0.6, 0.3, 0.2, 0, 0, 0, 0, 0, 0, 1, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0.6, 0.5, 0.2, 0.1, 0, 0, 0, 0, 0, 0, 0, 1]] ],
[[[1, 0.3, 0.4, 0.2, 0.5, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0.1, 0.6, 0.3, 0.2, 0, 0, 0, 0, 0, 0, 1, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0.6, 0.5, 0.2, 0.1, 0, 0, 0, 0, 0, 0, 0, 1]] ],
[[[1, 0.3, 0.4, 0.2, 0.5, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0.1, 0.6, 0.3, 0.2, 0, 0, 0, 0, 0, 0, 1, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0.6, 0.5, 0.2, 0.1, 0, 0, 0, 0, 0, 0, 0, 1]] ],
[[[1, 0.3, 0.4, 0.2, 0.5, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0.1, 0.6, 0.3, 0.2, 0, 0, 0, 0, 0, 0, 1, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0.6, 0.5, 0.2, 0.1, 0, 0, 0, 0, 0, 0, 0, 1]] ],
[[[1, 0.3, 0.4, 0.2, 0.5, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0.1, 0.6, 0.3, 0.2, 0, 0, 0, 0, 0, 0, 1, 0]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0.6, 0.5, 0.2, 0.1, 0, 0, 0, 0, 0, 0, 0, 1]] ],
]
)
X_val = np.random.rand(5, 448, 448, 3)
y_val = y_train.copy()
model.fit(X_train, y_train,
validation_data=(X_val, y_val),
shuffle=True,
epochs=10,
)
# pdb.set_trace()
if __name__ == '__main__':
main()
但是我遇到一个错误:
ValueError: No gradients provided for any variable: ['conv2d/kernel:0', 'conv2d/bias:0', 'block1_conv2/kernel:0',
'block1_conv2 / bias:0','block2_conv1 / kernel:0','block2_conv1 / bias:0', 'block2_conv2 / kernel:0','block2_conv2 / bias:0', 'block3_conv1 / kernel:0','block3_conv1 / bias:0', 'block3_conv2 / kernel:0','block3_conv2 / bias:0', 'block3_conv3 / kernel:0','block3_conv3 / bias:0', 'block4_conv1 / kernel:0','block4_conv1 / bias:0', 'block4_conv2 / kernel:0','block4_conv2 / bias:0', 'block4_conv3 / kernel:0','block4_conv3 / bias:0', 'block5_conv1 / kernel:0','block5_conv1 / bias:0', 'block5_conv2 / kernel:0','block5_conv2 / bias:0', 'block5_conv3 / kernel:0','block5_conv3 / bias:0','dense / kernel:0', 'dense / bias:0','dense_1 / kernel:0','dense_1 / bias:0']。
我使用的是TF 2.1.0,但是如果使用TF 1.13.0,也会出现错误:
ValueError:操作具有
None
的渐变。请确认 您所有的操作都定义了渐变(即 可区分的)。不带渐变的常见操作:K.argmax,K.round, 埃瓦尔。
但是,如果我在注释行中使用Keras后端函数,则它可以工作。请帮助我,非常感谢。