Py学习  »  Python

Python Keras-ImageDataGenerator中的自定义标签

Cubilla • 5 年前 • 1491 次点击  

我目前正在创建一个CNN模型来分类字体是否 Arial Verdana , Times New Roman Georgia . 总而言之 16 类,因为我还考虑了检测字体是否 regular , bold , italics bold italics . 所以 4 fonts * 4 styles = 16 classes .

Training data set : 800 image patches of 256 * 256 dimension (50 for each class)
Validation data set : 320 image patches of 256 * 256 dimension (20 for each class)
Testing data set : 160 image patches of 256 * 256 dimension (10 for each class)

以下是我的初始代码:

import numpy as np
import keras
from keras import backend as K
from keras.models import Sequential
from keras.layers import Activation
from keras.layers.core import Dense, Flatten
from keras.optimizers import Adam
from keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import *
from matplotlib import pyplot as plt
import itertools
import matplotlib.pyplot as plt
import pickle


 image_width = 256
 image_height = 256

 train_path = 'font_model_data/train'
 valid_path =  'font_model_data/valid'
 test_path = 'font_model_data/test'


  train_batches = ImageDataGenerator().flow_from_directory(train_path, target_size=(image_width, image_height), classes=['1','2','3','4', '5', '6', '7', '8', '9', '10', '11', '12','13', '14', '15', '16'], batch_size = 16)
 valid_batches = ImageDataGenerator().flow_from_directory(valid_path, target_size=(image_width, image_height), classes=['1','2','3','4', '5', '6', '7', '8', '9', '10', '11', '12','13', '14', '15', '16'], batch_size = 16)
 test_batches = ImageDataGenerator().flow_from_directory(test_path, target_size=(image_width, 
 image_height), classes=['1','2','3','4', '5', '6', '7', '8', '9', '10', '11', '12','13', '14', '15', '16'], batch_size = 160)


 imgs, labels = next(train_batches)
 print(labels)

#CNN model
model = Sequential([
    Conv2D(32, (3,3), activation='relu', input_shape=(image_width, image_height, 3)),
    Flatten(),
    Dense(**16**, activation='softmax'), # I want to make it 4
])

我计划在网络中有4个输出节点:

4 Output Nodes (4 bits):
Class 01 - 0000
Class 02 - 0001
Class 03 - 0010
Class 04 - 0011
Class 05 - 0100
Class 06 - 0101
Class 07 - 0110
Class 08 - 0111
Class 09 - 1000
Class 10 - 1001
Class 11 - 1010
Class 12 - 1011
Class 13 - 1100
Class 14 - 1101
Class 15 - 1110
Class 16 - 1111

ImageDataGenerator 是一个 16 bits 标签

[[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

 labels = [[0,0,0,0],
 [0,0,0,1],
 [0,0,1,0],
 [0,0,1,1],
 [0,1,0,0],
 [0,1,0,1],
 [0,1,1,0],
 [0,1,1,1],
 [1,0,0,0],
 [1,0,0,1],
 [1,0,1,0],
 [1,0,1,1],
 [1,1,0,0],
 [1,1,0,1],
 [1,1,1,0],
 [1,1,1,1]]

其目的是使我的网络/最后一个密集层的输出节点 16个 4

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/55349
 
1491 次点击  
文章 [ 2 ]  |  最新文章 5 年前
Vito
Reply   •   1 楼
Vito    5 年前

我的回答是不行的。不能将输出层仅转换为4个单元,因为有16个类要分类。如果要简化网络,请尝试减少隐藏单元的数量,以查看网络是否不合适或不合适。如果它太适合你,你可以降低你的网络的复杂性。如果不合适的话。这表明你需要更复杂的网络。如果你真的想减少输出层的单位数。也许我能想到的一种方法是,你可以先对字体进行分类。这需要4个单位。然后检测什么是风格。这还需要4个单位。然后结合两个输出的概率。我不确定这是否可行。你可以试试。

Nicolas Gervais
Reply   •   2 楼
Nicolas Gervais    5 年前

这就是你已经拥有的:

custom_labels = ['0000',  '0001', '0010', '0011', '0100', '0101', '0110', '0111',
                 '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111']

output = [[0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
            [0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
            [0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
            [1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
            [0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
            [0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
            [0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
            [0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
            [0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
            [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]]

你需要得到 1 :

import numpy as np

column = np.argmax(output, axis=1)
Out[10]: array([ 1,  2,  3,  0,  2,  9,  7,  4,  2, 15], dtype=int64)

使用此选项,可以选择相应的自定义标签:

array(['0001', '0010', '0011', '0000', '0010', '1001', '0111', '0100',
       '0010', '1111'], dtype='<U4')

但是你想要的是一个列表,但是作为单独的整数:

final_labels = np.array([list(i) for i in np.array(custom_labels)[column]]).astype(int)
array([[0, 0, 0, 1],
       [0, 0, 1, 0],
       [0, 0, 1, 1],
       [0, 0, 0, 0],
       [0, 0, 1, 0],
       [1, 0, 0, 1],
       [0, 1, 1, 1],
       [0, 1, 0, 0],
       [0, 0, 1, 0],
       [1, 1, 1, 1]])