【问题标题】:Getting an UnboundLocalError before the start of neural network training在神经网络训练开始前获取 UnboundLocalError
【发布时间】:2020-08-16 19:04:29
【问题描述】:

我正在尝试在 Google Colab 上运行我的代码,但出现错误:

UnboundLocalError: local variable 'logs' referenced before assignment

如果我删除“行”steps_per_epoch = train_stepsvalidation_steps = val_steps,代码是可执行的。问题在于,然后在步数上创建了一个无限循环,因为神经网络不知道在该 epoch 期间要执行多少步。

这是我的代码:

batch = 16
num_classes = 2
num_epochs = 300
img_width = 200
img_height = 200

train_data_size = [f for f in listdir(train_data_path) if isfile(join(train_data_path, f))]
val_data_size = [f for f in listdir(val_data_path) if isfile(join(val_data_path, f))]

train_steps = len(train_data_size) // batch
val_steps = len(val_data_size) // batch

train_datagen = ImageDataGenerator()
test_datagen = ImageDataGenerator()

train_generator = train_datagen.flow_from_directory(
    train_data_path,
    target_size=(img_width, img_height),
    batch_size=batch,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    val_data_path,
    target_size=(img_width, img_height),
    batch_size=batch,
    class_mode='categorical')

model = createModel()

opt = optimizers.RMSprop(learning_rate=0.0000001, decay=1e-6)

model.compile(loss='categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

history = model.fit(
    train_generator,
    epochs=num_epochs,
    steps_per_epoch=train_steps,
    callbacks=[checkpoint, csv_logger],
    validation_data=validation_generator,
    validation_steps=val_steps)

完整的错误信息:

Mounted at /content/drive
2.2.0-rc3 #Tensorflow version
Found 10018 images belonging to 2 classes.
Found 1336 images belonging to 2 classes.
WARNING:tensorflow:`period` argument is deprecated. Please use `save_freq` to specify the frequency in number of batches seen.
Epoch 1/300
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-7-dda79f001d12> in <module>()
    102     callbacks=[checkpoint, csv_logger],
    103     validation_data=validation_generator,
--> 104     validation_steps=val_steps)


1 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
    857               logs = tmp_logs  # No error, now safe to assign to logs.
    858               callbacks.on_train_batch_end(step, logs)
--> 859         epoch_logs = copy.copy(logs)
    860 
    861         # Run validation.

UnboundLocalError: local variable 'logs' referenced before assignment

我应该如何解决它?

【问题讨论】:

    标签: python tensorflow keras google-colaboratory


    【解决方案1】:

    batch_size 确定每个 mini batch 中的样本数。它的最大值是所有样本的数量,它的最小值是1,导致随机梯度下降。

    我能够在 colab 中使用 tensorflow 版本 = 2.2.0rc3 重新创建您的错误。当您提供的batch_size(在您的情况下为batch)大于验证数据集中的记录数时,会发生此错误。

    请参阅下面我用来重新创建错误的代码,我已经打印了数据集和批量大小的所有统计信息。

    import tensorflow as tf
    print(tf.__version__)
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
    from tensorflow.keras.preprocessing.image import ImageDataGenerator
    from tensorflow.keras.optimizers import Adam
    from keras import backend as K
    
    import os
    import numpy as np
    import matplotlib.pyplot as plt
    
    _URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
    
    path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)
    
    PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')
    
    train_dir = os.path.join(PATH, 'train')
    validation_dir = os.path.join(PATH, 'validation')
    
    batch_size = 1001
    epochs = 15
    IMG_HEIGHT = 150
    IMG_WIDTH = 150
    print("batch_size:",batch_size)
    
    train_data_size_cat = [f for f in os.listdir(train_cats_dir) if os.path.isfile(os.path.join(train_cats_dir, f))]
    train_data_size_dog = [f for f in os.listdir(train_dogs_dir) if os.path.isfile(os.path.join(train_dogs_dir, f))]
    
    val_data_size_cat = [f for f in os.listdir(validation_cats_dir) if os.path.isfile(os.path.join(validation_cats_dir, f))]
    val_data_size_dog = [f for f in os.listdir(validation_dogs_dir) if os.path.isfile(os.path.join(validation_dogs_dir, f))]
    
    train_steps = (len(train_data_size_cat) + len(train_data_size_dog)) // batch_size
    print("Total number of training records:",(len(train_data_size_cat) + len(train_data_size_dog)))
    print("steps_per_epoch:",train_steps)
    
    val_steps = (len(val_data_size_cat) + len(val_data_size_dog)) // batch_size
    print("Total number of testing records:",(len(val_data_size_cat) + len(val_data_size_dog)))
    print("val_steps:",val_steps)
    
    train_image_generator = ImageDataGenerator(rescale=1./255,brightness_range=[0.5,1.5]) # Generator for our training data
    validation_image_generator = ImageDataGenerator(rescale=1./255,brightness_range=[0.5,1.5]) # Generator for our validation data
    
    train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                               directory=train_dir,
                                                               shuffle=True,
                                                               target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                               class_mode='binary')
    
    val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size,
                                                                  directory=validation_dir,
                                                                  target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                                  class_mode='binary')
    
    model = Sequential([
        Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH ,3)),
        MaxPooling2D(),
        Conv2D(32, 3, padding='same', activation='relu'),
        MaxPooling2D(),
        Conv2D(64, 3, padding='same', activation='relu'),
        MaxPooling2D(),
        Flatten(),
        Dense(512, activation='relu'),
        Dense(1)
    ])
    
    adam = Adam(lr=0.01)
    
    model.compile(optimizer=adam, 
              loss=tf.keras.losses.binary_crossentropy,
              metrics=['accuracy'])
    
    history = model.fit_generator(
              train_data_gen,
              steps_per_epoch=train_steps,
              epochs=epochs,
              validation_data=val_data_gen,
              validation_steps=val_steps)
    

    输出 -

    2.2.0-rc3
    batch_size: 1001
    Total number of training records: 2000
    steps_per_epoch: 1
    Total number of testing records: 1000
    val_steps: 0
    Found 2000 images belonging to 2 classes.
    Found 1000 images belonging to 2 classes.
    Epoch 1/15
    1/1 [==============================] - ETA: 0s - loss: 7.4582 - accuracy: 0.5165
    ---------------------------------------------------------------------------
    UnboundLocalError                         Traceback (most recent call last)
    <ipython-input-17-dd9ba773718a> in <module>()
         77           epochs=epochs,
         78           validation_data=val_data_gen,
    ---> 79           validation_steps=val_steps)
    
    5 frames
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in evaluate(self, x, y, batch_size, verbose, sample_weight, steps, callbacks, max_queue_size, workers, use_multiprocessing, return_dict)
       1092       callbacks.on_test_end()
       1093 
    -> 1094       logs = tf_utils.to_numpy_or_python_type(logs)
       1095       if return_dict:
       1096         return logs
    
    UnboundLocalError: local variable 'logs' referenced before assignment
    

    解决方案-

    batch_size(在您的情况下为batch)减小到更小的尺寸,以便在训练期间可以更均匀地划分。例如,如果我在上述程序中将batch_size 更改为 128,则它可以正常工作。

    固定代码 -

    import tensorflow as tf
    print(tf.__version__)
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
    from tensorflow.keras.preprocessing.image import ImageDataGenerator
    from tensorflow.keras.optimizers import Adam
    from keras import backend as K
    
    import os
    import numpy as np
    import matplotlib.pyplot as plt
    
    _URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
    
    path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)
    
    PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')
    
    train_dir = os.path.join(PATH, 'train')
    validation_dir = os.path.join(PATH, 'validation')
    
    batch_size = 128
    epochs = 15
    IMG_HEIGHT = 150
    IMG_WIDTH = 150
    print("batch_size:",batch_size)
    
    train_data_size_cat = [f for f in os.listdir(train_cats_dir) if os.path.isfile(os.path.join(train_cats_dir, f))]
    train_data_size_dog = [f for f in os.listdir(train_dogs_dir) if os.path.isfile(os.path.join(train_dogs_dir, f))]
    
    val_data_size_cat = [f for f in os.listdir(validation_cats_dir) if os.path.isfile(os.path.join(validation_cats_dir, f))]
    val_data_size_dog = [f for f in os.listdir(validation_dogs_dir) if os.path.isfile(os.path.join(validation_dogs_dir, f))]
    
    train_steps = (len(train_data_size_cat) + len(train_data_size_dog)) // batch_size
    print("Total number of training records:",(len(train_data_size_cat) + len(train_data_size_dog)))
    print("steps_per_epoch:",train_steps)
    
    val_steps = (len(val_data_size_cat) + len(val_data_size_dog)) // batch_size
    print("Total number of testing records:",(len(val_data_size_cat) + len(val_data_size_dog)))
    print("val_steps:",val_steps)
    
    train_image_generator = ImageDataGenerator(rescale=1./255,brightness_range=[0.5,1.5]) # Generator for our training data
    validation_image_generator = ImageDataGenerator(rescale=1./255,brightness_range=[0.5,1.5]) # Generator for our validation data
    
    train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                               directory=train_dir,
                                                               shuffle=True,
                                                               target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                               class_mode='binary')
    
    val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size,
                                                                  directory=validation_dir,
                                                                  target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                                  class_mode='binary')
    
    model = Sequential([
        Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH ,3)),
        MaxPooling2D(),
        Conv2D(32, 3, padding='same', activation='relu'),
        MaxPooling2D(),
        Conv2D(64, 3, padding='same', activation='relu'),
        MaxPooling2D(),
        Flatten(),
        Dense(512, activation='relu'),
        Dense(1)
    ])
    
    adam = Adam(lr=0.01)
    
    model.compile(optimizer=adam, 
              loss=tf.keras.losses.binary_crossentropy,
              metrics=['accuracy'])
    
    history = model.fit_generator(
              train_data_gen,
              steps_per_epoch=train_steps,
              epochs=epochs,
              validation_data=val_data_gen,
              validation_steps=val_steps)
    

    输出 -

    2.2.0-rc3
    batch_size: 128
    Total number of training records: 2000
    steps_per_epoch: 15
    Total number of testing records: 1000
    val_steps: 7
    Found 2000 images belonging to 2 classes.
    Found 1000 images belonging to 2 classes.
    Epoch 1/15
    15/15 [==============================] - 29s 2s/step - loss: 7.6643 - accuracy: 0.5031 - val_loss: 7.6436 - val_accuracy: 0.5045
    Epoch 2/15
    15/15 [==============================] - 29s 2s/step - loss: 7.8217 - accuracy: 0.4947 - val_loss: 7.8158 - val_accuracy: 0.4933
    Epoch 3/15
    15/15 [==============================] - 29s 2s/step - loss: 7.6819 - accuracy: 0.5011 - val_loss: 7.6780 - val_accuracy: 0.5022
    Epoch 4/15
    15/15 [==============================] - 29s 2s/step - loss: 7.7494 - accuracy: 0.4995 - val_loss: 7.6436 - val_accuracy: 0.5045
    Epoch 5/15
    15/15 [==============================] - 28s 2s/step - loss: 7.5277 - accuracy: 0.5123 - val_loss: 7.7297 - val_accuracy: 0.4989
    Epoch 6/15
    15/15 [==============================] - 29s 2s/step - loss: 7.9214 - accuracy: 0.4877 - val_loss: 7.7813 - val_accuracy: 0.4955
    Epoch 7/15
    15/15 [==============================] - 28s 2s/step - loss: 7.6884 - accuracy: 0.5032 - val_loss: 7.6436 - val_accuracy: 0.5045
    Epoch 8/15
    15/15 [==============================] - 28s 2s/step - loss: 7.8426 - accuracy: 0.4904 - val_loss: 7.6953 - val_accuracy: 0.5011
    Epoch 9/15
    15/15 [==============================] - 29s 2s/step - loss: 7.5759 - accuracy: 0.5075 - val_loss: 7.8330 - val_accuracy: 0.4922
    Epoch 10/15
    15/15 [==============================] - 28s 2s/step - loss: 7.6643 - accuracy: 0.5032 - val_loss: 7.6953 - val_accuracy: 0.5011
    Epoch 11/15
    15/15 [==============================] - 29s 2s/step - loss: 7.7655 - accuracy: 0.4952 - val_loss: 7.7297 - val_accuracy: 0.4989
    Epoch 12/15
    15/15 [==============================] - 28s 2s/step - loss: 7.6884 - accuracy: 0.5032 - val_loss: 7.7297 - val_accuracy: 0.4989
    Epoch 13/15
    15/15 [==============================] - 28s 2s/step - loss: 7.8362 - accuracy: 0.4915 - val_loss: 7.6953 - val_accuracy: 0.5011
    Epoch 14/15
    15/15 [==============================] - 28s 2s/step - loss: 7.4634 - accuracy: 0.5150 - val_loss: 7.6608 - val_accuracy: 0.5033
    Epoch 15/15
    15/15 [==============================] - 28s 2s/step - loss: 7.8603 - accuracy: 0.4931 - val_loss: 7.7125 - val_accuracy: 0.5000
    

    希望这能回答您的问题。快乐学习。

    【讨论】:

    • @Alechandro - 如果它回答了您的问题,请您接受并投票赞成。谢谢。
    猜你喜欢
    • 2015-06-04
    • 2011-04-07
    • 1970-01-01
    • 2016-07-01
    • 2018-06-11
    • 2016-06-22
    • 1970-01-01
    • 2010-11-20
    • 2019-09-15
    相关资源
    最近更新 更多