اذهب إلى المحتوى
  • 0

السؤال

نشر

أحاول تدريب شبكة عصبية (هذه الشبكة عبارة عن تجميع طبقات RNN) لكن يظهر لي الخطأ في الكود التالي:

from keras.layers import Dense,Embedding,SimpleRNN
from keras.datasets import imdb
from keras.preprocessing import sequence
from keras.models import Sequential
max_features = 1000
maxlen = 20
batch_size = 64
print('Loading data...')
(input_train, y_train), (input_test, y_test) = imdb.load_data(
num_words=max_features)
print(len(input_train), 'train sequences')
print(len(input_test), 'test sequences')
print('Pad sequences (samples x time)')
input_train = sequence.pad_sequences(input_train, maxlen=maxlen)
input_test = sequence.pad_sequences(input_test, maxlen=maxlen)
print('input_train shape:', input_train.shape)
model = Sequential()
Loading data...
25000 train sequences
25000 test sequences
Pad sequences (samples x time)
input_train shape: (25000, 20)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-45-586f07f93ca3> in <module>
     18 model.add(Embedding(max_features, 16))
     19 model.add(SimpleRNN(16))
---> 20 model.add(SimpleRNN(16))
     21 model.add(Dense(1, activation='sigmoid'))
     22 model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])

~\anaconda3\lib\site-packages\tensorflow\python\training\tracking\base.py in _method_wrapper(self, *args, **kwargs)
    515     self._self_setattr_tracking = False  # pylint: disable=protected-access
    516     try:
--> 517       result = method(self, *args, **kwargs)
    518     finally:
    519       self._self_setattr_tracking = previous_value  # pylint: disable=protected-access

~\anaconda3\lib\site-packages\tensorflow\python\keras\engine\sequential.py in add(self, layer)
    221       # If the model is being built continuously on top of an input layer:
    222       # refresh its output.
--> 223       output_tensor = layer(self.outputs[0])
    224       if len(nest.flatten(output_tensor)) != 1:
    225         raise ValueError(SINGLE_LAYER_OUTPUT_ERROR_MSG)

~\anaconda3\lib\site-packages\tensorflow\python\keras\layers\recurrent.py in __call__(self, inputs, initial_state, constants, **kwargs)
    658 
    659     if initial_state is None and constants is None:
--> 660       return super(RNN, self).__call__(inputs, **kwargs)
    661 
    662     # If any of `initial_state` or `constants` are specified and are Keras

~\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in __call__(self, *args, **kwargs)
    950     if _in_functional_construction_mode(self, inputs, args, kwargs, input_list):
    951       return self._functional_construction_call(inputs, args, kwargs,
--> 952                                                 input_list)
    953 
    954     # Maintains info about the `Layer.call` stack.

~\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in _functional_construction_call(self, inputs, args, kwargs, input_list)
   1089         # Check input assumptions set after layer building, e.g. input shape.
   1090         outputs = self._keras_tensor_symbolic_call(
-> 1091             inputs, input_masks, args, kwargs)
   1092 
   1093         if outputs is None:

~\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in _keras_tensor_symbolic_call(self, inputs, input_masks, args, kwargs)
    820       return nest.map_structure(keras_tensor.KerasTensor, output_signature)
    821     else:
--> 822       return self._infer_output_signature(inputs, args, kwargs, input_masks)
    823 
    824   def _infer_output_signature(self, inputs, args, kwargs, input_masks):

~\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in _infer_output_signature(self, inputs, args, kwargs, input_masks)
    860           # overridden).
    861           # TODO(kaftan): do we maybe_build here, or have we already done it?
--> 862           self._maybe_build(inputs)
    863           outputs = call_fn(inputs, *args, **kwargs)
    864 

~\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in _maybe_build(self, inputs)
   2683     if not self.built:
   2684       input_spec.assert_input_compatibility(
-> 2685           self.input_spec, inputs, self.name)
   2686       input_list = nest.flatten(inputs)
   2687       if input_list and self._dtype_policy.compute_dtype is None:

~\anaconda3\lib\site-packages\tensorflow\python\keras\engine\input_spec.py in assert_input_compatibility(input_spec, inputs, layer_name)
    221                          'expected ndim=' + str(spec.ndim) + ', found ndim=' +
    222                          str(ndim) + '. Full shape received: ' +
--> 223                          str(tuple(shape)))
    224     if spec.max_ndim is not None:
    225       ndim = x.shape.rank

ValueError: Input 0 of layer simple_rnn_20 is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: (None, 16)


model.add(Embedding(max_features, 16))
model.add(SimpleRNN(16))
model.add(SimpleRNN(16))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
history = model.fit(input_train, y_train,
epochs=2,
batch_size=128,
validation_split=0.2)

 

Recommended Posts

  • 2
نشر

المشكلة تحدث عند محاولة إدخال خرج طبقة ال RNN الأولى إلى طبقة RNN الثانية.
إليك مايلي:

طبقات ال RNN بأنواعها المختلفة تعمل في وضعين:
الأول يرد كامل الخرج كسلسلة متتابعة من ال timestep وبالتالي يكون الخرج هو مصفوفة tensor ثلاثية الأبعاد  (batch_size, timesteps, output_features).
أما الوضع الثاني فيرد فقط آخر خرج لكل سلسلة إدخال، وبالتالي يكون الخرج ثنائي الأبعاد  (batch_size, output_features).
ويتم التحكم بنمط الإخراج باستخدام الوسيط return_sequences الذي يأخذ قيمة بوليانية، في حالة True فيكون الخرج هو الوضع الأول وفي حالة False يكون الوضع الثاني، وافتراضياً يكون False ، أي الوضع الثاني.
وكما نعلم أن طبقات الRNN تحتاج كدخل (batch_size, sequence_length, features)
وأنت تقوم بتكديس طبقتي RNN وبالتالي خرج الأولى سيكون دخل الثانية لذلك يجب أن يكون خرج الأولى  3D  أي يجب أن يكون الوضع الأول. لكن أنت تشغل الوضع الأول وبالتالي سيعطي خطأ، لأنها تحتاج 3D وتعتطيها 2D، لذا لحل المشكلة يجب أن نضبط return_sequences على True.

from keras.layers import Dense,Embedding,SimpleRNN
from keras.datasets import imdb
from keras.preprocessing import sequence
from keras.models import Sequential
max_features = 1000
maxlen = 20
batch_size = 64
print('Loading data...')
(input_train, y_train), (input_test, y_test) = imdb.load_data(
num_words=max_features)
print(len(input_train), 'train sequences')
print(len(input_test), 'test sequences')
print('Pad sequences (samples x time)')
input_train = sequence.pad_sequences(input_train, maxlen=maxlen)
input_test = sequence.pad_sequences(input_test, maxlen=maxlen)
print('input_train shape:', input_train.shape)
model = Sequential()
model.add(Embedding(max_features, 16))
model.add(SimpleRNN(16, return_sequences=True))
model.add(SimpleRNN(16))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
history = model.fit(input_train, y_train,
epochs=2,
batch_size=128,
validation_split=0.2)
'''
Loading data...
25000 train sequences
25000 test sequences
Pad sequences (samples x time)
input_train shape: (25000, 20)
Epoch 1/2
157/157 [==============================] - 4s 14ms/step - loss: 0.6751 - acc: 0.5501 - val_loss: 0.5692 - val_acc: 0.7026
Epoch 2/2
157/157 [==============================] - 2s 10ms/step - loss: 0.5229 - acc: 0.7427 - val_loss: 0.5801 - val_acc: 0.6912
'''

 

  • 0
نشر

الخطأ كما وضح @Ali Haidar Ahmadينتج عند الإنتقال من طبقة لأخرى، بشكل افتراضي يحتوي ناتج طبقة RNN على متجه واحد لكل عينة. هذا المتجه هو خرج RNN المقابل لآخر خطوة زمنية time step ، ويحتوي على معلومات حول تسلسل الإدخال بأكمله و يكون شكله هو (batch_size, units) حيث تتوافق units مع الرقم الممرر للنموذج لعدد الوحدات. بالتالي، لمعالجة المشكلة يجب إضافة return_sequences=True والتي تقوم بإرجاع التسلسل كامل للقيم الناتجة من تنفيذ النموذج في الطبقة المعنية (هنا الطبقة الأولى لأنها ستمرر القيم لSimpleRNN مرة أخرى) و سيكون الشكل الممرر عبارة عن (batch_size, timesteps, units).

لاحظ الإختلاف في المثالين الثاليين:

  1. بدون retrun_sequence:
    from keras.models import Model
    from keras.layers import Input, SimpleRNN
    from numpy as np
    # تعريف النموذج
    inputs1 = Input(shape=(3, 1))
    lstm1 = SimpleRNN(1)(inputs1)
    model = Model(inputs=inputs1, outputs=lstm1)
    # تعريف البيانات المدخلة
    data = np.array([0.1, 0.2, 0.3]).reshape((1,3,1))
    # توقع البيانات بإستخدام النموذج و طباعة الناتج
    print(model.predict(data))

     
  2. بإستخدام return_sequence:
    from keras.models import Model
    from keras.layers import Input, SimpleRNN
    import numpy as np
    # تعريف النموذج
    inputs1 = Input(shape=(3, 1))
    lstm1 = SimpleRNN(1, return_sequences=True)(inputs1)
    model = Model(inputs=inputs1, outputs=lstm1)
    # تعريف البيانات المدخلة
    data = np.array([0.1, 0.2, 0.3]).reshape((1,3,1))
    # توقع البيانات بإستخدام النموذج و طباعة الناتج
    print(model.predict(data))

     

لاحظ الفرق في الناتج، في المرة الأولى لدينا مدخل ب3 time steps وهو ناتجه عبارة عن قيمة واحدة من تنفيذ دالة SimpleRNN وهنا قيم الأوزان و القيم المبدئية يتم إختيارها عشوائياً. أما في الحالة الثانية فالغرض كان إخراج نتيجة تطبيق SimpleRNN لكل قيمة مدخلة من ال3 time steps. لذلك كان الناتج 3 قيم منفصلة، لاحظ الناتج الذي تحصلت عليه:

# بدون إرجاع القيم لكل سلسلة زمنية
[[0.6872494]]

# مع إرجاع الناتج لكل سلسلة زمنية منفصلة
[[[0.07889937]
  [0.0790627 ]
  [0.15682352]]]

 

 

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...