用于二元特征提取的多标签分类CNN中间层的第二损失函数

时间:2018-08-13 23:46:36

标签: hash keras multilabel-classification loss-function multipleoutputs

我尝试通过多标签分类cnn提取二进制代码,我在顺序模型中提取了二进制代码。但是为了获得更有效的代码,我对Out_1应用了第二个损失函数,该函数使Dense_48的激活(S型)与0.5之间的平方误差最大。有2000张图片,所有图片的大小均为256x256 rgb。

#coding=utf-8



import cv2

import glob

import numpy as np

import sys,os

import matplotlib

matplotlib.use('Agg')

import time

import glob

import os, os.path

import re

import scipy.io


numbers = re.compile(r'(\d+)')

def numericalSort(value):

    parts = numbers.split(value)

    parts[1::2] = map(int, parts[1::2])

    return parts

train_X = []

files = sorted(glob.glob("/home/ubuntu/caffe/data/lamda_2/lamdaPics/*.jpg"),  

key=numericalSort)

for myFile in files:

    image = cv2.imread (myFile)

    train_X.append (image)

train_X = np.array(train_X, dtype=np.float32)

train_Y = scipy.io.loadmat('/targets.mat') 

del train_Y['__version__']

del train_Y['__header__']

del train_Y['__globals__']

train_Y=list(train_Y.values())

train_Y = np.reshape(train_Y, (2000,5))


from sklearn.model_selection import train_test_split

train_X,valid_X,train_label,valid_label = train_test_split(train_X, train_Y, test_size=0.01 ,random_state=13)

import keras

from keras.models import Sequential,Input,Model

from keras.layers import Dense, Dropout, Flatten

from keras.layers import Conv2D, MaxPooling2D

from keras.layers.normalization import BatchNormalization

from keras.layers.advanced_activations import LeakyReLU

batch_size = 64

epochs = 32

num_classes = train_Y.shape[1]

hash_bits = 48

print(train_X.shape)

print(valid_X.shape)

print(train_label.shape)

print(valid_label.shape)

print(train_X.shape[1])

print(train_Y.shape[1])

from keras.utils import plot_model

from keras.models import Model

from keras.layers import Input

from keras.layers import Dense

from keras.layers import Flatten

from keras.layers.convolutional import Conv2D

from keras.layers.pooling import MaxPooling2D

from keras.layers.merge import concatenate

visible          = Input(shape=(256,256,3),name = 'visible')

conv_1           = Conv2D(32, kernel_size=4, activation='linear')(visible)

lReLU_1          = LeakyReLU(alpha=0.1)(conv_1)

MaxPool_1        = MaxPooling2D((2, 2),padding='same')(lReLU_1)

Drop_1           = Dropout(0.25)(MaxPool_1)

conv_2           = Conv2D(64, kernel_size=3, activation='linear')(Drop_1)

lReLU_2          = LeakyReLU(alpha=0.1)(conv_2)

MaxPool_2        = MaxPooling2D((2, 2),padding='same')(lReLU_2)

Drop_2           = Dropout(0.25)(MaxPool_2)

conv_3           = Conv2D(128, kernel_size=3, activation='linear')(Drop_2)

lReLU_3          = LeakyReLU(alpha=0.1)(conv_3)

MaxPool_3        = MaxPooling2D((2, 2),padding='same')(lReLU_3)

Drop_3           = Dropout(0.4)(MaxPool_3)

Flat_1           = Flatten()(Drop_3)

Dense_128        = Dense(128, activation='linear')(Flat_1)

lReLU_4          = LeakyReLU(alpha=0.1)(Dense_128)

Drop_4           = Dropout(0.4)(lReLU_4)

Dense_48         = Dense(48, activation='sigmoid')(Drop_4)

Out_1            = Dense_48

Dense_5          = Dense(5, activation='sigmoid')(Dense_48)

Out_2            = Dense_5

merge            = concatenate([Out_1, Out_2])

model = Model(inputs=visible, outputs=[Out_1, Out_2])


print(model.summary())

plot_model(model, to_file='mult_loss.png')




e=0.5

import keras.backend as K

def c_loss (Out_1, e):
    return (K.sum((Out_1-e)**2) ) * (-1/48)



from keras.optimizers import SGD

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

model.compile(loss=[c_loss, 'categorical_crossentropy'], loss_weights=[1., 1.], optimizer=sgd, metrics=['accuracy'])

train_X = train_X.astype("float32")

valid_X = valid_X.astype("float32")

train_X /= 255

valid_X /= 255

print(train_X.shape)

print(valid_X.shape)

print(train_label.shape)

print(valid_label.shape)


train_dropout = model.fit(train_X, [train_label, train_label],
        shuffle=True,  batch_size=batch_size,epochs=epochs,verbose=1,
        validation_data=(valid_X, [valid_label, valid_label]))

任何建议或解决方案表示赞赏...

1 个答案:

答案 0 :(得分:0)

Keras中的多输出模型期望将np arrays的列表传递到model.fit(),每个输出一个数组。在您的情况下,输出是两次相同。尝试以下方法:

model.fit(train_X, [train_label, train_label],
    validation_data=(valid_X, [valid_label, valid_label])