Как решить ошибку «не имеет атрибута» в коде Python при попытке запустить один код, связанный с CNN? - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь запустить модифицированный код Python, связанный с CNN, по этой ссылке: https://github.com/nephashi/GaitRecognitionCNN

и получить ошибку как:

Файл "/root/PycharmProjects/CNNCheck/Run_CNN.py", строка 60, в model.add (Conv2D121 (8, (5, 5), padding = 'valid'))

Файл "/root/PycharmProjects/CNNCheck/layers/Conv2D121.py", строка 35, в init

self.data_format = conv_utils.normalize_data_format (data_format)

AttributeError: модуль 'keras.utils.conv_utils' не имеет атрибута 'normalize_data_format'

Я создал проект python с именем CNNCheck

, который содержит файл python с именем: Run_CNN.py и один каталог с именем: layer, который содержит файл с именем: Conv2D121.py и кодируется следующим образом:

Run_CNN.py

import keras
from keras.layers import Activation, Dense
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
import numpy as np
import cv2
import os
from layers.Conv2D121 import Conv2D121


path1="/home/sanjay/CASIA_B90PerfectCentrallyAlinged_Resized_with_140by140_Energy_Image/"
#path1="/home/sanjay/CASIA_B90PerfectCentrallyAlinged_CODEI_OneCycle_frames-20_Resized_with_140by140_Energy_Image/"
all_images = []
all_labels = []
subjects = os.listdir(path1)
numberOfSubject = len(subjects)
print('Number of Subjects: ', numberOfSubject)
for number1 in range(0, numberOfSubject):  # numberOfSubject
    path2 = (path1 + subjects[number1] + '/')
    sequences = os.listdir(path2);
    numberOfsequences = len(sequences)
    for number2 in range(4, numberOfsequences):
        path3 = path2 + sequences[number2]
        img = cv2.imread(path3 , 0)
        img = img.reshape(140, 140, 1)
        all_images.append(img)
        all_labels.append(number1)
x_train = np.array(all_images)
y_train = np.array(all_labels)
y_train = keras.utils.to_categorical(y_train)


all_images = []
all_labels = []

for number1 in range(0, numberOfSubject):  # numberOfSubject
    path2 = (path1 + subjects[number1] + '/')
    sequences = os.listdir(path2);
    numberOfsequences = len(sequences)
    for number2 in range(0, 4):
        path3 = path2 + sequences[number2]
        img = cv2.imread(path3 , 0)
        img = img.reshape(140, 140, 1)
        all_images.append(img)
        all_labels.append(number1)
x_test = np.array(all_images)
y_test = np.array(all_labels)
y_test = keras.utils.to_categorical(y_test)

batch_size = 4
num_classes = 123
epochs = 10000

model = Sequential()
model.add(Conv2D(8, (5, 5), padding='valid',
                 input_shape=(140, 140, 1)))
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
model.add(Conv2D121(8, (5, 5), padding='valid'))
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
model.add(Conv2D121(8, (5, 5), padding='valid'))
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
model.add(Conv2D121(8, (5, 5), padding='valid'))
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2,2), strides=2, padding='valid'))
model.add(Flatten())
model.add(Dense(num_classes, input_shape=(200,)))
model.add(Activation('softmax'))
model.summary()

Conv2D121.py

from keras import backend as K
from keras import initializers
from keras import regularizers
from keras import constraints
from keras.engine.base_layer import Layer
from keras.engine.base_layer import InputSpec
from keras.utils import conv_utils

# 121 means one-to-one connection :)
class Conv2D121(Layer):

    def __init__(self, filters,
                 kernel_size,
                 strides=1,
                 rank=2,
                 padding='valid',
                 data_format=None,
                 use_bias=True,
                 kernel_initializer='glorot_uniform',
                 bias_initializer='zeros',
                 kernel_regularizer=None,
                 bias_regularizer=None,
                 kernel_constraint=None,
                 bias_constraint=None,
                 **kwargs
                 ):
        super(Conv2D121, self).__init__(**kwargs)
        self.rank = rank
        self.filters = filters
        self.kernel_size = conv_utils.normalize_tuple(kernel_size, rank, 'kernel_size')
        self.strides = conv_utils.normalize_tuple(strides, rank, 'strides')
        # normalize_padding: 检查padding的值,只有['valid', 'same', 'causal']三个值合法
        self.padding = conv_utils.normalize_padding(padding)
        # data_format: 检查
        self.data_format = conv_utils.normalize_data_format(data_format)
        self.use_bias = use_bias,
        self.kernel_initializer = initializers.get(kernel_initializer)
        self.bias_initializer = initializers.get(bias_initializer)
        self.kernel_regularizer = regularizers.get(kernel_regularizer)
        self.bias_regularizer = regularizers.get(bias_regularizer)
        self.kernel_constraint = constraints.get(kernel_constraint)
        self.bias_constraint = constraints.get(bias_constraint)
        self.input_spec = InputSpec(ndim=self.rank + 2)

    def build(self, input_shape):
        if self.data_format == 'channels_first':
            channel_axis = 1
        else:
            channel_axis = -1
        if input_shape[channel_axis] is None:
            raise ValueError('The channel dimension of the inputs '
                             'should be defined. Found `None`.')
        input_dim = input_shape[channel_axis]
        self.input_dim = input_dim
        if input_dim != self.filters:
            raise ValueError('Because nature of one-to-one connnection, '
                             'input dimension must be equal to filters number')
        kernel_shape = self.kernel_size + (1, 1)

        self.kernels = []

        for i in range(input_dim):
            self.kernels.append(self.add_weight(
                shape=kernel_shape,
                # initializer=self.kernel_initializer,
                initializer=self.kernel_initializer,
                name='kernel' + str(i),
                regularizer=self.kernel_regularizer,
                constraint=self.kernel_constraint
            ))

        if self.use_bias:
            self.bias = self.add_weight(
                shape=(self.input_dim,),
                initializer=self.bias_initializer,
                name='bias',
                regularizer=self.bias_regularizer,
                constraint=self.bias_constraint
            )
        else:
            self.bias = None

        self.input_spec = InputSpec(ndim=self.rank + 2,
                                    axes={channel_axis: input_dim})
        self.built = True

    def call(self, inputs, **kwargs):
        if self.rank != 2:
            raise ValueError('currently this layer only support 2D data.')

        input_slices = []

        # now we need to slice the input_dim dimension input and do convolution
        for i in range(self.input_dim):
            slice = K.expand_dims(inputs[:, :, :, i], axis=3)
            input_slices.append(slice)

        output_slices = []

        for i in range(self.input_dim):
            slice = K.conv2d(
                input_slices[i],
                self.kernels[i],
                strides=self.strides,
                padding=self.padding,
                data_format=self.data_format,
            )
            output_slices.append(slice)

        output = K.concatenate(output_slices, axis=3)

        if (self.use_bias):
            output = K.bias_add(
                output,
                self.bias,
                data_format=self.data_format
            )

        return output

    def compute_output_shape(self, input_shape):
        if self.data_format == 'channels_last':
            space = input_shape[1:-1]
            new_space = []
            for i in range(len(space)):
                new_dim = conv_utils.conv_output_length(
                    space[i],
                    self.kernel_size[i],
                    padding=self.padding,
                    stride=self.strides[i])
                new_space.append(new_dim)
            return (input_shape[0],) + tuple(new_space) + (self.filters,)
        if self.data_format == 'channels_first':
            space = input_shape[2:]
            new_space = []
            for i in range(len(space)):
                new_dim = conv_utils.conv_output_length(
                    space[i],
                    self.kernel_size[i],
                    padding=self.padding,
                    stride=self.strides[i])
                new_space.append(new_dim)
            return (input_shape[0], self.filters) + tuple(new_space)

Как мы можем устранить ошибку, возникающую как:

Файл "/root/PycharmProjects/CNNCheck/Run_CNN.py", строка 60, в model.add (Conv2D121 (8, (5, 5), padding = 'valid'))

Файл "/root/PycharmProjects/CNNCheck/layers/Conv2D121.py", строка 35, в init

self.data_format = conv_utils.normalize_data_format (data_format)

AttributeError: модуль 'keras.utils.conv_utils' не имеет атрибута 'normalize_data_format'

1 Ответ

0 голосов
/ 30 апреля 2019

возникла проблема с версией keras.

Я установил keras 2.2.0, а не keras 2.2.4

, поэтому проблема решена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...