我一直在尝试运行一个暹罗网络。在这一点上,我只是试图使其运行。我当前的迭代使用pandas数据框来确定要加载的图像。数据框在Anchor_Image,Positive_Image,Negative_Image下具有Anchor_Id,Positive_Id,Negative_Id的列以及相应的文件名。我正在使用三重损失函数来确定图像嵌入的差异。
现在我的错误是该模型需要3个数组,但是只接收1个数组的列表。我知道generator_generator_triplet(如下所示)会将这些流放入列表中,但这似乎可以在该模型的其他迭代中使用。我以前的问题是,我需要最终的嵌入模型具有一个Dense层,该层的节点数与类别完全一样(大约5000个)。这对我来说没有任何意义,我认为问题与模型一起提供了一个热标签向量以及X值(图像)。
其中一些代码来自各种stackoverflow和Keras github帖子,但我无法使所有功能都在一个引擎盖下工作。
如果有人可以帮助我,甚至通过修改下面的内容,我也会欣喜若狂。我已经阅读了所有有关三重态丢失的文章,但没有特别提到使用多个flow_from_dataframe实例。
bs = 32
train_gen = ImageDataGenerator(rescale = 1/.255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = False)
def generate_generator_triplet(generator, df, path1, batch_size, img_height, img_width):
gen_anchor = generator.flow_from_dataframe(dataframe = df,
directory = path1,
x_col = 'Anchor_Image',
y_col = 'Anchor_Id',
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_size,
shuffle=False,
seed=8,
drop_duplicates = False)
gen_pos = generator.flow_from_dataframe(dataframe = df,
directory = path1,
x_col = 'Pos_Image',
y_col = 'Pos_Id',
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_size,
shuffle=False,
seed=8,
drop_duplicates = False)
gen_neg = generator.flow_from_dataframe(dataframe = df,
directory = path1,
x_col = 'Neg_Image',
y_col = 'Neg_Id',
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_size,
shuffle=False,
seed=8,
drop_duplicates = False)
while True:
Anchori = gen_anchor.next()
Posi = gen_pos.next()
Negi = gen_neg.next()
yield [Anchori[0], Posi[0], Negi[0]], Anchori[1]
inputgenerator = generate_generator_triplet(generator=train_gen,
df = new,
path1=path,
batch_size=bs,
img_height=128,
img_width=128)
## Triplet Loss
ALPHA = .2
def triplet_loss(y_true, y_pred, alpha = ALPHA):
anchor, pos, neg = y_pred[0], y_pred[1], y_pred[2]
pos_dist = K.sum(K.square(anchor - pos), axis = 0)
neg_dist = K.sum(K.square(anchor - neg), axis = 0)
loss = K.maximum(pos_dist - neg_dist + alpha, 0.0)
return loss
## Model Construction
data_input = Input(shape = [128,128,3])
siam = Conv2D(64, (4,4), strides = (1,1))(data_input)
siam = Activation(activation = 'relu')(siam)
siam = Conv2D(128, (5,5), strides = (1,1))(siam)
siam = Activation(activation = 'relu')(siam)
siam = MaxPooling2D()(siam)
siam = Flatten()(siam)
siam = Dense(64)(siam)
siam = Activation(activation = 'relu')(siam)
siam = Dense(512)(siam)
out = Activation(activation = 'sigmoid')(siam)
siam_model = Model(inputs = data_input, outputs = out)
anchor_input = Input(shape = [128, 128, 3])
pos_input = Input(shape = [128, 128, 3])
neg_input = Input(shape = [128, 128, 3])
anchor_embed = siam_model(anchor_input)
pos_embed = siam_model(pos_input)
neg_embed = siam_model(neg_input)
optimizer = Adam(0.00006)
siamese_net = Model(inputs = [anchor_input, pos_input, neg_input],
outputs = [anchor_embed, pos_embed, neg_embed])
siamese_net.compile(optimizer = optimizer, loss = triplet_loss, metrics = ['accuracy'])
siamese_net.summary()
siamese_net.fit_generator(inputgenerator,
steps_per_epoch = len(new)/bs,
epochs = 5,
shuffle = False
#,validation_data = ([test_left, test_right], test_targets)
)