「日本古典籍字形データセット」で遊ぶ | moskomule log

「日本古典籍字形データセット」で遊ぶ

日本語版MNIST,というわけではないけれど日本古典籍字形データセットの識別をkerasで実装したresnetによって行った.現在validation accuracyは93.3%.少なくとも自分よりはきちんと分類できるようだ.

このデータセットには2017年1月現在,「8点の画像データから切り取ったくずし字1,521文字種の字形データ86,176文字」が収録されているので,そのまま1521に分類している.

例

今回はMNIST的に使うので,つまり文脈を考慮しないので変体仮名の「志」(し)と漢字としての「志」とを区別する,というようなタスクも含まれてしまうが,特に考慮しない.kerasImageDataGeneratorで前処理を一括して行う.本当はもう少し丁寧にした方がいいのかもしれないけれど,とりあえず.


# data generator
train_datagen = ImageDataGenerator(
    shear_range=0.05,
    width_shift_range=0.05,
    height_shift_range=0.05,
    rotation_range=10,
    fill_mode="constant",
    cval=200,
    zoom_range=0.2)
train_generator = train_datagen.flow_from_directory(
    'train',
    color_mode="grayscale",
    target_size=target_size,
    batch_size=batch_size,
    class_mode='categorical'
)

val_datagen = ImageDataGenerator()
val_generator = val_datagen.flow_from_directory(
    'val',
    color_mode="grayscale",
    target_size=target_size,
    batch_size=batch_size,
    class_mode='categorical'
)

training dataには変形を施した.resnetはkeras.jsを参考にして実装(下記のres_a,res_b).

# model
input_layer = Input(shape=input_shape)
x = Convolution2D(nb_filters, 4, 4, subsample=(2,2))(input_layer)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = MaxPooling2D(pool_size, strides=stride_size)(x)
x = res_a([32,32,128])(x)
x = res_b([32,32,128])(x)
x = res_b([32,32,128])(x)
x = res_a([64,64,256])(x)
x = res_b([64,64,256])(x)
x = res_b([128,128,256])(x)
x = res_a([128,128,512])(x)
x = res_b([128,128,512])(x)
x = res_b([256,256,512])(x)
x = AveragePooling2D((4,4))(x)
x = Flatten()(x)
output_layer = Dense(nb_classes, activation='softmax')(x)

model = Model(input=input_layer, output=output_layer)
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
comments powered by Disqus