Несмотря на то, что я новичок в этой теме, я пытаюсь реализовать программу CNN, которую можно использовать для распознавания изображений без использования Keras. В настоящее время я использую python с Jupyter/Google Colab.
После исправления нескольких других ошибок, которые возникли в моем коде, теперь у меня есть эта ошибка:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/client/session.py:1761: UserWarning: An interactive session is already active. This can cause out-of-memory errors in some cases. You must explicitly call `InteractiveSession.close()` to release resources held by the other session(s).
warnings.warn('An interactive session is already active. This can '
Training the model....
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-28-1af250ed46b3> in <module>()
108 for i in range(num_iterations):
109 # Get the next batch of images
--> 110 batch = mnist.train.next_batch(batch_size) #third got an error for this line -
111 # x_batch, y_batch = mnist.train.next_batch(batch_size)
112
AttributeError: 'dict' object has no attribute 'train'
Это мой текущий код:
!pip install tensorflow_datasets
!pip install --upgrade tensorflow
!pip install tensorflow-datasets
!pip install mnist
#!pip install tensorflow.examples.tutorials.mnist
import argparse
print ('argparse version: ', argparse.__version__)
import mnist
print ('MNIST version: ', mnist.__version__)
import tensorflow_datasets
print ('tensorflow_datasets version: ', tensorflow_datasets.__version__)
import tensorflow.compat.v1 as tf
print ('tf version: ', tf.__version__)
tf.disable_v2_behavior()
#from tensorflow.examples.tutorials.mnist import input_data
#def build_arg_parser():
# parser = argparse.ArgumentParser(description='Build a CNN classifier \
# using MNIST data')
# parser.add_argument('--input-dir', dest='input_dir', type=str,
# default='./mnist_data', help='Directory for storing data')
# return parser
def get_weights(shape):
data = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(data)
def get_biases(shape):
data = tf.constant(0.1, shape=shape)
return tf.Variable(data)
def create_layer(shape):
# Get the weights and biases
W = get_weights(shape)
b = get_biases([shape[-1]])
return W, b
def convolution_2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1],
padding='SAME')
def max_pooling(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
if __name__ == '__main__':
#args = build_arg_parser().parse_args()
# Get the MNIST data
mnist = tensorflow_datasets.load('mnist')
# The images are 28x28, so create the input layer
# with 784 neurons (28x28=784)
x = tf.placeholder(tf.float32, [None, 784])
# Reshape 'x' into a 4D tensor
x_image = tf.reshape(x, [-1, 28, 28, 1])
# Define the first convolutional layer
W_conv1, b_conv1 = create_layer([5, 5, 1, 32])
# Convolve the image with weight tensor, add the
# bias, and then apply the ReLU function
h_conv1 = tf.nn.relu(convolution_2d(x_image, W_conv1) + b_conv1)
# Apply the max pooling operator
h_pool1 = max_pooling(h_conv1)
# Define the second convolutional layer
W_conv2, b_conv2 = create_layer([5, 5, 32, 64])
# Convolve the output of previous layer with the
# weight tensor, add the bias, and then apply
# the ReLU function
h_conv2 = tf.nn.relu(convolution_2d(h_pool1, W_conv2) + b_conv2)
# Apply the max pooling operator
h_pool2 = max_pooling(h_conv2)
# Define the fully connected layer
W_fc1, b_fc1 = create_layer([7 * 7 * 64, 1024])
# Reshape the output of the previous layer
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
# Multiply the output of previous layer by the
# weight tensor, add the bias, and then apply
# the ReLU function
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
# Define the dropout layer using a probability placeholder
# for all the neurons
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
# Define the readout layer (output layer)
W_fc2, b_fc2 = create_layer([1024, 10])
y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
# Define the entropy loss and the optimizer
y_loss = tf.placeholder(tf.float32, [None, 10])
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y_loss, logits=y_conv))
optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss)
# Define the accuracy computation
predicted = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_loss, 1))
accuracy = tf.reduce_mean(tf.cast(predicted, tf.float32))
# Create and run a session
sess = tf.InteractiveSession()
init = tf.initialize_all_variables()
sess.run(init)
# Start training
num_iterations = 21000
batch_size = 75
print('\nTraining the model....')
for i in range(num_iterations):
# Get the next batch of images
batch = mnist.train.next_batch(batch_size)
# Print progress
if i % 50 == 0:
cur_accuracy = accuracy.eval(feed_dict = {
x: batch[0], y_loss: batch[1], keep_prob: 1.0})
print('Iteration', i, ', Accuracy =', cur_accuracy)
Train on the current batch
optimizer.run(feed_dict = {x: batch[0], y_loss: batch[1], keep_prob: 0.5})
# Compute accuracy using test data
print('Test accuracy =', accuracy.eval(feed_dict = {
x: mnist.test.images, y_loss: mnist.test.labels,
keep_prob: 1.0}))
Я нашел несколько сообщений с точно таким же кодом, как и у меня, но все их реализации каким-то образом запускаются. Я пытался искать решения, но не нашел того, который работал для меня.
В одном сообщении, которое я нашел, говорилось, что «базовые словари не имеют атрибута« поезд »». Это заставило меня задуматься, почему я тогда получил эту ошибку, если словари обычно не имеют этих атрибутов, но у других был такой же код.
В другом посте использовалась строка:
x_batch, y_batch = mnist.train.next_batch(batch_size)
вместо строки:
batch = mnist.train.next_batch(batch_size)
но ни один из них, похоже, не работал для меня. Ни одно из других изменений/решений, которые я пытался изучить, также не сработало.
Кто-нибудь знает, как исправить эту ошибку без атрибута?
Похоже, ваш код устарел/устарел, поэтому он больше не работает. Для библиотеки TensorFlow характерно очень частое изменение, и они также часто ломают интерфейс, поэтому старый код перестает работать.
Во-первых, вы пытаетесь import mnist
, это какой-то неправильный модуль, он почти не содержит кода и кажется бесполезным, возможно, раньше он был полезен и работал, но не сейчас.
Также функция mnist.train.next_batch(...)
больше не работает, так как она больше не реализована внутри набора данных mnist, возможно, она работала и раньше.
Я решил реализовать свой собственный вспомогательный класс MyDS
, который реализует все эти недостающие функции. Ниже приведен ваш полный исправленный код, включая мой класс (в начале):
if __name__ == '__main__':
import tensorflow.compat.v1 as tf
tf.enable_eager_execution()
import tensorflow_datasets as tfds
class MyDS(object):
class SubDS(object):
import numpy as np
def __init__(self, ds, *, one_hot):
np = self.__class__.np
self.ds = [e for e in ds.as_numpy_iterator()]
self.sds = {(k + 's') : np.stack([
(e[k] if len(e[k].shape) > 0 else e[k][None]).reshape(-1) for e in self.ds
], 0) for k in self.ds[0].keys()}
self.one_hot = one_hot
if one_hot is not None:
self.max_one_hot = np.max(self.sds[one_hot + 's'])
def _to_one_hot(self, a, maxv):
np = self.__class__.np
na = np.zeros((a.shape[0], maxv + 1), dtype = a.dtype)
for i, e in enumerate(a[:, 0]):
na[i, e] = True
return na
def _apply_one_hot(self, key, maxv):
assert maxv >= self.max_one_hot, (maxv, self.max_one_hot)
self.max_one_hot = maxv
self.sds[key + 's'] = self._to_one_hot(self.sds[key + 's'], self.max_one_hot)
def next_batch(self, num = 16):
np = self.__class__.np
idx = np.random.choice(len(self.ds), num)
res = {k : np.stack([
(self.ds[i][k] if len(self.ds[i][k].shape) > 0 else self.ds[i][k][None]).reshape(-1) for i in idx
], 0) for k in self.ds[0].keys()}
if self.one_hot is not None:
res[self.one_hot] = self._to_one_hot(res[self.one_hot], self.max_one_hot)
for i, (k, v) in enumerate(list(res.items())):
res[i] = v
return res
def __getattr__(self, name):
if name not in self.__dict__['sds']:
return self.__dict__[name]
return self.__dict__['sds'][name]
def __init__(self, name, *, one_hot = None):
self.ds = tfds.load(name)
self.sds = {}
for k, v in self.ds.items():
self.sds[k] = self.__class__.SubDS(self.ds[k], one_hot = one_hot)
if one_hot is not None:
maxh = max(e.max_one_hot for e in self.sds.values())
for e in self.sds.values():
e._apply_one_hot(one_hot, maxh)
def __getattr__(self, name):
if name not in self.__dict__['sds']:
return self.__dict__[name]
return self.__dict__['sds'][name]
# Get the MNIST data
mnist = MyDS('mnist', one_hot = 'label') # tensorflow_datasets.load('mnist')
import argparse
print ('argparse version: ', argparse.__version__)
#import mnist
#print ('MNIST version: ', mnist.__version__)
#import tensorflow_datasets
print ('tensorflow_datasets version: ', tfds.__version__)
#import tensorflow.compat.v1 as tf
print ('tf version: ', tf.__version__)
tf.disable_eager_execution()
tf.disable_v2_behavior()
#from tensorflow.examples.tutorials.mnist import input_data
#def build_arg_parser():
# parser = argparse.ArgumentParser(description='Build a CNN classifier \
# using MNIST data')
# parser.add_argument('--input-dir', dest='input_dir', type=str,
# default='./mnist_data', help='Directory for storing data')
# return parser
def get_weights(shape):
data = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(data)
def get_biases(shape):
data = tf.constant(0.1, shape=shape)
return tf.Variable(data)
def create_layer(shape):
# Get the weights and biases
W = get_weights(shape)
b = get_biases([shape[-1]])
return W, b
def convolution_2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1],
padding='SAME')
def max_pooling(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
#args = build_arg_parser().parse_args()
# The images are 28x28, so create the input layer
# with 784 neurons (28x28=784)
x = tf.placeholder(tf.float32, [None, 784])
# Reshape 'x' into a 4D tensor
x_image = tf.reshape(x, [-1, 28, 28, 1])
# Define the first convolutional layer
W_conv1, b_conv1 = create_layer([5, 5, 1, 32])
# Convolve the image with weight tensor, add the
# bias, and then apply the ReLU function
h_conv1 = tf.nn.relu(convolution_2d(x_image, W_conv1) + b_conv1)
# Apply the max pooling operator
h_pool1 = max_pooling(h_conv1)
# Define the second convolutional layer
W_conv2, b_conv2 = create_layer([5, 5, 32, 64])
# Convolve the output of previous layer with the
# weight tensor, add the bias, and then apply
# the ReLU function
h_conv2 = tf.nn.relu(convolution_2d(h_pool1, W_conv2) + b_conv2)
# Apply the max pooling operator
h_pool2 = max_pooling(h_conv2)
# Define the fully connected layer
W_fc1, b_fc1 = create_layer([7 * 7 * 64, 1024])
# Reshape the output of the previous layer
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
# Multiply the output of previous layer by the
# weight tensor, add the bias, and then apply
# the ReLU function
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
# Define the dropout layer using a probability placeholder
# for all the neurons
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
# Define the readout layer (output layer)
W_fc2, b_fc2 = create_layer([1024, 10])
y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
# Define the entropy loss and the optimizer
y_loss = tf.placeholder(tf.float32, [None, 10])
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y_loss, logits=y_conv))
optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss)
# Define the accuracy computation
predicted = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_loss, 1))
accuracy = tf.reduce_mean(tf.cast(predicted, tf.float32))
# Create and run a session
sess = tf.InteractiveSession()
init = tf.initialize_all_variables()
sess.run(init)
# Start training
num_iterations = 21000
batch_size = 75
print('\nTraining the model....')
for i in range(num_iterations):
# Get the next batch of images
batch = mnist.train.next_batch(batch_size)
# Print progress
if i % 50 == 0:
cur_accuracy = accuracy.eval(feed_dict = {
x: batch[0], y_loss: batch[1], keep_prob: 1.0})
print('Iteration', i, ', Accuracy =', cur_accuracy)
# Train on the current batch
optimizer.run(feed_dict = {x: batch[0], y_loss: batch[1], keep_prob: 0.5})
# Compute accuracy using test data
print('Test accuracy =', accuracy.eval(feed_dict = {
x: mnist.test.images, y_loss: mnist.test.labels,
keep_prob: 1.0}))
@adigioia Просто найдите слово mnist
во всем коде. Я уверен, что вы используете его как переменную (не модуль) не только в одном месте, но и в нескольких. Я только что показал вам пример только одного неправильного использования, остальное вы должны искать сами. Общее правило: если вы импортируете модуль с именем x
, не используйте переменную с именем x
где-либо в коде, иначе имя вашего модуля будет перезаписано или затенено.
@adigioia Кроме того, я вижу, что вы используете блокнот Jupyter. Вот почему ваша переменная с именем mnist
кэшируется в состоянии ячеек. Вам нужно очистить состояние ноутбука и повторно запустить все ячейки.
@adigioia Извините, я обнаружил, что ваш установленный модуль pip install mnist
совершенно неправильный, он почти не содержит кода. Вероятно, это не связано с тензорным потоком. Вы должны найти и использовать какой-то другой модуль. Я постараюсь найти правильный модуль для вас, чтобы делать такие вещи.
Почти весь этот код был написан заранее и передан мне профессором для редактирования и использования в исследовательском проекте, поэтому сначала я должен просмотреть и исправить все ошибки. На самом деле я только что перезагрузился и искал mnist в остальной части кода прямо перед тем, как увидел ваши комментарии - это определенно был хороший звонок! Теперь я получаю ту же ошибку, но вместо этого у mnist нет атрибута «поезд», поэтому я сейчас пытаюсь разобраться в этом.
Большое спасибо! Я определенно ценю вашу помощь в поиске! Поскольку этот код был предоставлен мне для использования в том виде, в каком он есть, мне немного сложно пойти и попытаться вернуться к тому, что сделал автор, чтобы затем исправить это.
@adigioia Это очень обычное дело для TensorFlow, они очень часто меняют и нарушают структуру интерфейсов и модулей, поэтому даже немного устаревший код часто больше не работает. Мне кажется, что модуль, который использовался в вашем коде (MNIST), уже не тот. Теперь нам нужно найти его новое правильное расположение где-то внутри пакета tensorflow. Вероятно, внутри этого модуля изменились и функции.
О, хорошо, я понятия не имел, так как это самый первый раз, когда мне приходилось работать с любым из этих пакетов или CNN раньше. Мне кажется немного странным, что люди будут продолжать делать это, если шансы на запуск кода невелики (будь то из-за того, что он немного устарел, или из-за других проблем). В настоящее время у меня установлен tensorflow 2.4.0, который, если посмотреть его сейчас, кажется самой новой версией. У меня возникли проблемы с поиском других пакетов для замены mnist, но я обязательно продолжу поиски!
В итоге я нашел еще один пакет под названием python-mnist отсюда pypi.org/project/python-mnist. Затем я вернулся к своему коду и изменил свою установку на !pip install python-mnist. Затем я изменил свой импорт на mnist import MNIST. Затем я перешел к своему коду и каждый раз, когда появлялся mnist.~~~, я менял его на MNIST. Теперь у меня есть ошибка «тип объекта« MNIST »не имеет атрибута« поезд »» в той же пакетной строке.
Тем не менее, теперь у меня есть ТОННА предупреждающих сообщений, которые говорят о том, что все эти разные вещи устарели. Я предполагаю, что, поскольку появилось сообщение о том, что многие вещи устарели, это согласуется с тем, что вы говорили о том, что код, который мне дали, вероятно, устарел, и поэтому он больше не работает должным образом?
@adigioia Я понял, что все недостающие функции были просто удалены в последней версии TensorFlow. Вот почему я решил повторно реализовать их с нуля. Смотрите мой обновленный ответ, он включает в себя мой вспомогательный класс MyDS
, который содержит все, чего не хватало. Мой класс интегрирован в ваш код, и полностью исправленный ваш код находится в моем ответе. Поскольку вы используете блокнот Jupyter, после копирования и вставки моего кода вам необходимо сбросить среду, в меню есть кнопка, например Reload/Reset environment and run all cells
. В моем блокноте Colab код работает отлично и после обучения дает точность 0.988
.
Я определенно должен вам огромное спасибо за то, что вы смогли сделать все это и помочь мне!! Я потратил некоторое время после своих последних комментариев, пытаясь продолжить поиск других пакетов, но все равно остался с пустыми руками, поэтому ваш комментарий / ответ - огромное облегчение! После 30-40 минут удовольствия от программы я остановил выполнение примерно на 11 000-й итерации и получил точность отдельных итераций от 0,82 (со 100-й итерации) до 1,0 (для многих других итераций).
Я попытался закомментировать раздел прогресса итерации печати, чтобы увидеть, ускорит ли это работу программы, но в итоге я получил сообщение об ошибке значения: tf.enable_eager_execution следует вызывать при запуске». точно такой же код, который я только что запускал, но в любом случае программа отлично работает - большое вам спасибо!
@adigioia Эта ошибка не связана с функцией печати. Причина проста - система Jupyter Notebook хранит все в памяти. Поэтому, если вы снова запускаете ячейки, они запускаются, начиная с того же глобального состояния, со всеми уже заполненными переменными. Другими словами запуск всех ячеек дважды - это не одно и то же. Двойной запуск - это то же самое, что добавление исходного кода дважды к одному и тому же сценарию и запуск. Определенно вторая половина кода может быть неработоспособной после первой половины. Другими словами, если вы повторно запускаете код, вам нужно сбросить всю среду. В меню есть что-то вроде Reset/Clear environment and run all cells
@adigioia Кстати, ты говоришь, что твоя тренировка длится полчаса. Вы можете загрузить свой скрипт (как это сделал я) на сайт Google https://colab.research.google.com, эта услуга бесплатна, если у вас есть аккаунт GMail, и позволяет вам использовать бесплатно (неограниченное время) довольно мощный графический процессор. В меню есть что-то вроде Environment / Select environment
и там можно выбрать GPU. По умолчанию среда графического процессора не включена, используется ЦП. Я загрузил свой скрипт из ответа, и его запуск на их графическом процессоре занял около 3-5 минут.
Я вернулся в Google Colab и только что попробовал ваше предложение о переходе на GPU! Если вы перейдете на вкладку «Среда выполнения», то там будет опция «Изменить тип среды выполнения», и там вы сможете выбрать GPU или TPU. Это определенно было намного быстрее - максимум 3 или 4 минуты! Все ваши комментарии/ответы были НЕВЕРОЯТНО полезными, и я определенно многому научился из этого поста! Большое спасибо!!
@adigioia Добро пожаловать! :) И счастливого Рождества и счастливого Нового года!
Спасибо!! Я надеюсь, что у вас было отличное Рождество, и у вас будет отличный Новый год :)
Привет, спасибо за попытку помочь! Я внес изменения, которые вы сказали, в имена переменных, но я почему-то все еще получаю ту же ошибку «объект 'dict' не имеет атрибута 'train'». Есть ли что-то еще, что должно быть изменено?