代码之家  ›  专栏  ›  技术社区  ›  Martin Ueding

对一幅大图像应用在瓷砖上训练的convnet分类器

  •  0
  • Martin Ueding  · 技术社区  · 4 年前

    我的任务是在文件的图片上找到某个字母。使用经典的计算机视觉,我将图像分割成字符。然后,我用一个神经网络对2525个像素的字符图像进行训练,将它们分为我想要的字符和所有其他字符。利用这个,我可以重建这些角色的位置。

    现在我想直接将convnet应用于整个图像,这样我就不必依赖于经典的分割。该网络是一个深度神经网络,由二维卷积、二维最大池层和稠密分类器组成。网络是这样的:

    Layer (type)                 Output Shape              Param #   
    =================================================================
    conv2d_61 (Conv2D)           (None, 23, 23, 32)        320       
    _________________________________________________________________
    max_pooling2d_50 (MaxPooling (None, 11, 11, 32)        0         
    _________________________________________________________________
    conv2d_62 (Conv2D)           (None, 9, 9, 64)          18496     
    _________________________________________________________________
    max_pooling2d_51 (MaxPooling (None, 4, 4, 64)          0         
    _________________________________________________________________
    flatten_46 (Flatten)         (None, 1024)              0         
    _________________________________________________________________
    dropout_5 (Dropout)          (None, 1024)              0         
    _________________________________________________________________
    dense_89 (Dense)             (None, 1)                 1025      
    =================================================================
    Total params: 19,841
    Trainable params: 19,841
    Non-trainable params: 0
    

    我知道我可以用经过训练的滤波器将卷积部分应用于整个图像。这将以更大空间维度的张量形式给出对这些过滤器的响应。但是为了分类,我需要使用经过训练的分类器来获取固定数量的空间信息。输入不同大小的图像会破坏这一点。

    到目前为止,我最好的想法是将图像分割成块,并将每个固定大小的块送入分类器。这似乎就是问题的答案 another question .

    是否存在更好的方法将经过训练的过滤器应用于整个图像,并可以使用经过训练的分类器进行某种局部分类?

    0 回复  |  直到 4 年前
        1
  •  0
  •   today    4 年前

    作为一种解决方案,我建议您使用 tf.image.extract_patches 函数从图像中提取面片,并对每个面片应用经过训练的分类器。这有几个好处:

    • 你会得到一个密集的响应图,你可以进一步处理,以准确地确定字母出现在整个图像中的位置。

    • 由于这是一个内置的TensorFlow Op,您可以通过将所有这些作为单个Keras模型实现和运行来简化流程,从而利用批处理以及加快CPU/GPU处理的优势。

    以下是解决方案的示意图:

    import tensorflow as tf
    from tensorflow.keras.layers import Input, Reshape, TimeDistributed
    
    whole_images = Input(shape=(img_rows, img_cols, 1))
    patches = tf.image.extract_patches(
        whole_images,
        sizes=[1, 25, 25, 1],
        strides=[1, 1, 1, 1], # you can choose to increase the stride if you don't want a dense classification map
        rates=[1, 1, 1, 1],
        padding='SAME'
    )
    # The `patches` would have a shape of `(batch_size, num_row_locs, num_col_locs, 25*25)`.
    # So we reshape it so that we can apply the classifier to each patch independently.
    reshaped_patches = Reshape((-1, 25, 25, 1))(patches)
    dense_map = TimeDistributed(letter_classifier)(reshaped_patches)
    # Reshape it back
    dense_map = Reshape(tf.shape(patches)[1:-1])(dense_map)
    
    # Construct the model
    image_classifier = Model(whole_images, dense_map)
    
    # Use it on the real images
    output = image_classifier(my_images)