Тензор (..., shape = (), dtype = int64) должен быть из того же графа, что и Tensor (..., shape = (), dtype = resource) Керас - PullRequest
2 голосов
/ 01 мая 2020

Я пытаюсь использовать Keras для запуска Conv2D net для чтения набора папок, содержащих изображения жестов из 20 млрд. Jester Я знаю, что Conv2D, вероятно, не будет работать, но Я хочу получить что-то, что я использовал прежде, чтобы работать правильно, прежде чем изменять слишком много кода. Тем не менее, я продолжаю сталкиваться с

ValueError: Tensor("training/Adamax/Const:0", shape=(), dtype=int64) must be from the same graph as Tensor("Adamax/iterations:0", shape=(), dtype=resource).

и не понимаю достаточно, чтобы это исправить. Я пробовал другие ответы по поводу сброса графика

import keras 
keras.backend.clear_session()

или

tf.reset_default_graph()

, но ни то, ни другое не работает.

Моя структура файла изображения похожа на : ../images/train/[Gesture]/[Sample]/Image001.png

, который является уровнем, более глубоким, чем я использовал ранее, но каталог flow_from_dory правильно выводит изображение и количество классов для наборов обучения и проверки

Found 3456570 images belonging to 27 classes.
Found 532578 images belonging to 27 classes.

Список Конда:

...
cudatoolkit               10.0.130                      0  
cudnn                     7.6.4                cuda10.0_0 
...
keras                     2.3.1                         0  
keras-applications        1.0.8                      py_0  
keras-base                2.3.1                    py37_0  
keras-gpu                 2.3.1                         0  
keras-preprocessing       1.1.0                      py_1  
...
tensorboard               1.14.0           py37hf484d3e_0  
tensorflow                1.14.0          gpu_py37h4491b45_0  
tensorflow-base           1.14.0          gpu_py37h8d69cac_0  
tensorflow-estimator      1.14.0                     py_0  
tensorflow-gpu            1.14.0               h0d30ee6_0  

Код:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import glob
import shutil
import pickle
import cv2
import numpy as np
import matplotlib.pyplot as plt
import random
from IPython.display import display
from PIL import Image

from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, BatchNormalization, Activation
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.convolutional import Conv3D, MaxPooling3D
from keras.constraints import maxnorm
from keras.utils import np_utils
from keras.preprocessing.image import ImageDataGenerator

import tensorflow as tf

os.environ["CUDA_VISIBLE_DEVICES"]="1"
tf.reset_default_graph()

# read in the training and validation labels
trainPairs = np.genfromtxt('/home/me/Videos/sign_language/jester-v1-train.csv', delimiter=';', skip_header=0, dtype=[('class', 'S12'),('sign','S50')])
trainLabels = [v for k,v in trainPairs]

validPairs = np.genfromtxt('/home/me/Videos/sign_language/jester-v1-validation.csv', delimiter=';', skip_header=0, dtype=[('class', 'S12'),('sign','S50')])
validLabels = [v for k,v in validPairs]

def copyDirectory(src, dest):
    try:
        shutil.copytree(src, dest)
    # Directories are the same
    except shutil.Error as e:
        print('Directory not copied. Error: %s' % e)
    # Any error saying that the directory doesn't exist
    except OSError as e:
        print('Directory not copied. Error: %s' % e)

source = '/media/me/other/20bn-jester-v1/'
dest = '/media/me/other/jester/validation/'

# counter = 0
# for k,v in validPairs:
#     counter = counter + 1
#     source_folder = source + k.decode("utf-8")
#     dest_folder = dest + v.decode("utf-8") + "/" + k.decode("utf-8")

#     if counter%100 == 0:        
#         print(k)
#         print(v)
#         print(counter)
#         print(source_folder)
#         print(dest_folder)

#     if os.path.isdir(source_folder):
#         if os.path.isdir(dest + v.decode("utf-8")):
#             copyDirectory(source_folder, dest_folder)        

#     if counter%1000 == 0:
#         print(counter)

datagen = ImageDataGenerator()

train_it = datagen.flow_from_directory('/media/me/other/jester/train/', class_mode='categorical', batch_size=64)
valid_it = datagen.flow_from_directory('/media/me/other/jester/validation/', class_mode='categorical', batch_size=64)
# test_it = datagen.flow_from_directory('/media/me/other/jester/test/', class_mode='binary', batch_size=64)

seed = 21
epochs = 5
optimizer = 'Adamax'

with tf.device("/cpu:0"):
    model = Sequential()

model = Sequential()


#model.add(Conv2D(32,(3,3), input_shape=(X_train.shape[1:]), padding='same'))
#TODO is this the right shape??
model.add(Conv2D(32,(3,3), input_shape=(256, 256, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(32, (3,3), input_shape=(3,32,32), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(Conv2D(64, (3,3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(Conv2D(128, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(BatchNormalization())

model.add(Flatten())
model.add(Dropout(0.2))
model.add(Dense(256, kernel_constraint=maxnorm(3)))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(BatchNormalization())

model.add(Dense(128, kernel_constraint=maxnorm(3)))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(BatchNormalization())

#TODO make this a variable
model.add(Dense(27))
model.add(Activation('softmax'))

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

### I think everything up to here is ok???

global graph
graph = tf.get_default_graph()

for layer in model.layers:
    print(layer.output_shape)

print(model.summary())

np.random.seed(seed)

image_batch_train, label_batch_train = next(iter(train_it))
print("Image batch shape: ", image_batch_train.shape)
print("Label batch shape: ", label_batch_train.shape)
dataset_labels = sorted(train_it.class_indices.items(), key=lambda pair:pair[1])
dataset_labels = np.array([key.title() for key, value in dataset_labels])

print(dataset_labels)

from keras import backend as K
K.clear_session()

import keras 
keras.backend.clear_session()

tf.reset_default_graph()
model.fit_generator(train_it, steps_per_epoch=16, validation_data=valid_it, validation_steps=8)

#scores = model.evaluate(test_it, steps=24, verbose=0)
#print("Accuracy: %.2f%%" % (scores[1]*100))

Редактировать 1: добавлены журналы

Traceback (most recent call last):

  File "<ipython-input-1-09b1bdd2e389>", line 152, in <module>
    model.fit_generator(train_it, steps_per_epoch=16, validation_data=valid_it, validation_steps=8)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/keras/engine/training.py", line 1732, in fit_generator
    initial_epoch=initial_epoch)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/keras/engine/training_generator.py", line 42, in fit_generator
    model._make_train_function()

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/keras/engine/training.py", line 316, in _make_train_function
    loss=self.total_loss)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/keras/optimizers.py", line 599, in get_updates
    self.updates = [K.update_add(self.iterations, 1)]

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py", line 1268, in update_add
    return tf_state_ops.assign_add(x, increment)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/tensorflow/python/ops/state_ops.py", line 195, in assign_add
    return ref.assign_add(value)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/tensorflow/python/ops/resource_variable_ops.py", line 1108, in assign_add
    name=name)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/tensorflow/python/ops/gen_resource_variable_ops.py", line 68, in assign_add_variable_op
    "AssignAddVariableOp", resource=resource, value=value, name=name)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py", line 366, in _apply_op_helper
    g = ops._get_graph_from_inputs(_Flatten(keywords.values()))

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 6135, in _get_graph_from_inputs
    _assert_same_graph(original_graph_element, graph_element)

  File "/home/me/Programs/anaconda3/envs/hand-gesture/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 6071, in _assert_same_graph
    (item, original_item))

ValueError: Tensor("training/Adamax/Const:0", shape=(), dtype=int64) must be from the same graph as Tensor("Adamax/iterations:0", shape=(), dtype=resource).

1 Ответ

0 голосов
/ 04 мая 2020

Проблема в том, что вы сбрасываете график по умолчанию перед тренировкой модели:

tf.reset_default_graph()  # <-- remove this line
model.fit_generator(train_it, steps_per_epoch=16, validation_data=valid_it, validation_steps=8)

Проблема заключается в следующем. Сначала вы сбрасываете график по умолчанию в начале, который, если ваш реальный скрипт не имеет больше кода до этого, на самом деле не имеет никакого значения, так как график по умолчанию пуст в этот момент. Затем вы создаете свою модель, и она создает операции на новом графике по умолчанию. Этот новый график по умолчанию - тот, с которым вы получаете позже:

graph = tf.get_default_graph()

Проблема в том, что после двойной очистки сеанса Keras (который также не оказывает никакого влияния) вы сбрасываете график по умолчанию снова. Когда вы вызываете fit, начинается процесс обучения и создаются некоторые новые графовые объекты модели Keras. Поскольку ваш график по умолчанию изменил его (потому что вы его сбросили), эти новые объекты создаются в графике, отличном от остальных объектов, что вызывает ошибку. Я думаю, что вы все еще можете сбросить график и заставить его работать, если вы используете прежний график по умолчанию во время обучения:

tf.reset_default_graph()
with graph.as_default():  # Use former default graph as default
    model.fit_generator(train_it, steps_per_epoch=16, validation_data=valid_it, validation_steps=8)

Я не совсем уверен, будет ли сеанс Keras по умолчанию работать всегда (так как возможно, он был создан для нового графика по умолчанию), но я думаю, что он должен ... В любом случае, если вы по какой-то причине хотите, чтобы ваша модель Keras была изолирована в своем собственном графике, вместо сброса графика вы можете сделать это следующим образом:

with tf.Graph().as_default() as graph:  # Make a new graph and use it as default
    # Make dataset
    # Make model
    # Train
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...