如何在训练和测试CNN模型进行图像分类时检查提取的特征?

时间:2018-01-28 11:46:39

标签: python machine-learning conv-neural-network feature-extraction scientific-computing

我正在使用CNN来训练和测试种子图像。我想知道:

  • 每层都会提取哪些功能?
  • 有没有办法以图形或图像格式表示它?
  • 如何定义分类器以仅提取特定功能?

    from keras.preprocessing.image import ImageDataGenerator
    from keras.models import Sequential
    from keras.layers import Conv2D, MaxPooling2D
    from keras.layers import Activation, Dropout, Flatten, Dense
    from keras import backend as K
    
    
    # dimensions of our images.
    img_width, img_height = 150, 150
    
    train_data_dir = 'Train_Walnut_Seed/train'
    validation_data_dir = 'Train_Walnut_Seed/validation'
    nb_train_samples = 70
    nb_validation_samples = 9
    epochs = 50
    batch_size = 16
    
    if K.image_data_format() == 'channels_first':
            input_shape = (3, img_width, img_height)
    else:
            input_shape = (img_width, img_height, 3)
    
    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=input_shape))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    model.add(Conv2D(32, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    model.add(Flatten())
    model.add(Dense(64))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1))
    model.add(Activation('sigmoid'))
    
    model.compile(loss='binary_crossentropy',
            optimizer='rmsprop',
            metrics=['accuracy'])
    
    # this is the augmentation configuration we will use for training
    train_datagen = ImageDataGenerator(
            rescale=1. / 255,
            shear_range=0.2,
            zoom_range=0.2,
            horizontal_flip=True)
    
    # this is the augmentation configuration we will use for testing:
    # only rescaling
    test_datagen = ImageDataGenerator(rescale=1. / 255)
    
    train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')
    
    validation_generator = test_datagen.flow_from_directory(
            validation_data_dir,
            target_size=(img_width, img_height),
            batch_size=batch_size,
            class_mode='binary')
    
    model.fit_generator(
            train_generator,
            steps_per_epoch=nb_train_samples // batch_size,
            epochs=epochs,
            validation_data=validation_generator,
            validation_steps=nb_validation_samples // batch_size)
    
    model.save('first_try_walnut.h5')
    

以上代码用于使用CNN训练分类器。如何在训练时直观地表示每一层的输出。 另外如何将我训练过的模型部署到protocolbuffer(.pb)文件中,以便在我的android项目中使用它

2 个答案:

答案 0 :(得分:0)

我认为最好的方法,或者至少我知道提取有用功能的最佳方式是使用自动编码器。
查看Keras博客中的this文章。

干杯,
加布里埃尔

答案 1 :(得分:0)

我知道这可能不再是问题,但我只是想添加一下,以防对其他人有用。由于CNN输出的功能并不是真正可读的,因此很难对其进行检查。一种方法是使用t-SNE,它可以直观地指示图像的哪些嵌入表示彼此靠近。实现此目的的另一种方法是使用“热图”,该图更详细地显示图像的哪些部分正在激活CNN的部分。这篇文章很好地解释了其中的一些技术:http://cs231n.github.io/understanding-cnn/

很难让分类器关注某些功能-您需要更改网络体系结构或使用图像预处理来强调您希望网络关注的功能。恐怕我真的不能提供更多细节。