keras的自定义损失不会减少吗?

时间:2018-08-05 06:54:21

标签: python tensorflow machine-learning keras deep-learning

我正在使用keras进行验证码识别问题,每张图片有四个字母。

我最后设置了四个“ S形”密集层,并将它们连接为一个张量(其中,网络形状的最终输出为(None,4 * 36))。其中4表示验证码长度,36表示字符大小。

我设置了自定义损失函数和准确性函数,但是损失没有减少吗?

这是怎么了?谁能解释一下,谢谢!

下面是我的代码:

  
      
  1. 验证码生成器
  2.   
def deal_img(img):
    kernel = np.ones((3,1), np.uint8)
    img = img_to_array(img).astype(np.uint8)
    img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) 
    blur = cv.GaussianBlur(img, (5, 5), 0)
    _, img = cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
    img = cv.dilate(img, kernel, iterations=1)
    img = cv.erode(img, kernel, iterations=1)
    return img.reshape(height,width,1)

def gen(batch_size=32):
    while True:
        imgs=[]
        labels = []
        for i in range(batch_size):
            random_str = ''.join([random.choice(characters) for j in range(4)])
            img = generator.generate_image(random_str)
            img = deal_img(img)
            imgs.append(img)
            y=np.zeros((len(characters)*4))
            for i,char in enumerate(random_str):
                y[characters.find(char)+i*len(characters)] = 1
            labels.append(y)   
        train_x = np.array(imgs)
        train_y = np.array(labels)
        yield train_x, train_y
  
      
  1. 模型
  2.   
input_tensor = Input(shape=(height, width, 1))
x = input_tensor

x = Conv2D(32, 3, padding='same', activation='relu')(x)
x = Conv2D(32, 3, padding='same', activation='relu')(x)
x = MaxPooling2D((2, 2))(x)


x = Conv2D(64, 3, padding='same', activation='relu')(x)
x = Conv2D(64, 3, padding='same', activation='relu')(x)
x = MaxPooling2D((2, 2))(x)

x = Conv2D(128, 3, padding='same', activation='relu')(x)
x = Conv2D(128, 3, padding='same',activation='relu')(x)
x = MaxPooling2D((2, 2))(x)

x = Flatten()(x)
x = Dropout(0.25)(x)

x = [Dense(n_class, activation='softmax', name='c%d'%(i+1))(x) for i in range(n_len)]
output = concatenate(x)
model = Model(inputs=input_tensor, outputs=output)
  
      
  1. 损失,acc和火车
  2.   
def my_acc(y_true, y_pred):
    predict = tf.reshape(y_pred, [-1, n_len, len(characters)])
    max_idx_p = tf.argmax(predict, 2)
    max_idx_l = tf.argmax(tf.reshape(y_true, [-1,n_len, len(characters)]), 2)
    correct_pred = tf.reduce_all(tf.equal(max_idx_p, max_idx_l),axis=1)
    return tf.reduce_mean(tf.cast(correct_pred, tf.float32))

def my_loss(y_true, y_pred):
    loss = tf.Variable(initial_value=0.0)
    for i in range(n_len):
        a = y_pred[:,i*36:(i+1)*36]
        b = y_true[:,i*36:(i+1)*36]
        loss += tf.keras.losses.categorical_crossentropy(b,a)
    return loss

model.compile(loss = my_loss,
          optimizer=tf.train.AdamOptimizer(0.1),
          metrics=[my_acc])
checkpointer = keras.callbacks.ModelCheckpoint(filepath='/output/weight.h5',#"output/weights.{epoch:02d}--{val_loss:.2f}-{val_my_acc:.4f}.hdf5", 
                           verbose=2, save_weights_only=True)
model.fit_generator(gen(64),steps_per_epoch=10000,epochs=1,verbose=1,validation_data=gen(100),validation_steps=1,callbacks=[checkpointer])

0 个答案:

没有答案