pytorch: NotImplementedError when trying to iterate a dataloader - pytorch

I am trying to create a custom IterableDataset in pytorch and split it into train, validation and test datasets using this answer https://stackoverflow.com/a/61818182/9478434 .
My dataset class is:
class EchoDataset(torch.utils.data.IterableDataset):
def __init__(self, delay=4, seq_length=15, size=1000):
super(EchoDataset).__init__()
self.delay = delay
self.seq_length = seq_length
self.size = size
def __len__(self):
return self.size
def __iter__(self):
""" Iterable dataset doesn't have to implement __getitem__.
Instead, we only need to implement __iter__ to return
an iterator (or generator).
"""
for _ in range(self.size):
seq = torch.tensor([random.choice(range(1, N + 1)) for i in range(self.seq_length)], dtype=torch.int64)
result = torch.cat((torch.zeros(self.delay), seq[:self.seq_length - self.delay])).type(torch.int64)
yield seq, result
And the dataset is created and splitted as:
DELAY = 4
DATASET_SIZE = 200000
ds = EchoDataset(delay=DELAY, size=DATASET_SIZE)
train_count = int(0.7 * DATASET_SIZE)
valid_count = int(0.2 * DATASET_SIZE)
test_count = DATASET_SIZE - train_count - valid_count
train_dataset, valid_dataset, test_dataset = torch.utils.data.random_split(
ds, (train_count, valid_count, test_count)
)
The problem is that when I want to iterate into the dataloader, I get NotImplementedError:
iterator = iter(train_dataset_loader)
print(next(iterator))
I get:
NotImplementedError: Caught NotImplementedError in DataLoader worker process 0.
Original Traceback (most recent call last):
File "venv/lib/python3.6/site-packages/torch/utils/data/_utils/worker.py", line 287, in _worker_loop
data = fetcher.fetch(index)
File "venv/lib/python3.6/site-packages/torch/utils/data/_utils/fetch.py", line 49, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File "venv/lib/python3.6/site-packages/torch/utils/data/_utils/fetch.py", line 49, in <listcomp>
data = [self.dataset[idx] for idx in possibly_batched_index]
File "venv/lib/python3.6/site-packages/torch/utils/data/dataset.py", line 363, in __getitem__
return self.dataset[self.indices[idx]]
File "venv/lib/python3.6/site-packages/torch/utils/data/dataset.py", line 69, in __getitem__
raise NotImplementedError
NotImplementedError
It seems the problem goes back to splitting the dataset and creating Subset objects since I can iterate through a Dataloader created from the original dataset (not splitted)

Related

KeyError when trying to fine tuning Bert for text classification

I am trying to fine tune Bert for text classification on my dataset and I am getting the following error:
KeyError: 'Indexing with integers (to access backend Encoding for a given batch index) is not available when using Python based tokenizers'
Here is the full error:
1/1 * Epoch (train): 0% 0/613 [00:00<?, ?it/s]Traceback (most recent call last):
File "train.py", line 47, in <module>
runner.train(
File "/usr/local/lib/python3.8/dist-packages/catalyst/runners/runner.py", line 377, in train
self.run()
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 422, in run
self._run_event("on_exception")
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 365, in _run_event
getattr(self, event)(self)
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 357, in on_exception
raise self.exception
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 419, in run
self._run()
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 410, in _run
self.engine.spawn(self._run_local)
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/engine.py", line 59, in spawn
return fn(*args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 405, in _run_local
self._run_experiment()
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 399, in _run_experiment
self._run_epoch()
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 391, in _run_epoch
self._run_loader()
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 384, in _run_loader
self._run_event("on_batch_start")
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 361, in _run_event
getattr(self, event)(self)
File "/usr/local/lib/python3.8/dist-packages/catalyst/runners/supervised.py", line 150, in on_batch_start
super().on_batch_start(runner)
File "/usr/local/lib/python3.8/dist-packages/catalyst/core/runner.py", line 321, in on_batch_start
self.batch_size = len(self.batch[0])
File "/usr/local/lib/python3.8/dist-packages/transformers/tokenization_utils_base.py", line 241, in __getitem__
raise KeyError(
KeyError: 'Indexing with integers (to access backend Encoding for a given batch index) is not available when using Python based tokenizers'
The code I am using for data preparation:
import logging
from pathlib import Path
from typing import List, Mapping, Tuple
import pandas as pd
import torch
from catalyst.utils import set_global_seed
from torch.utils.data import DataLoader, Dataset
from transformers import AutoTokenizer
class TextClassificationDataset(Dataset):
"""
Wrapper around Torch Dataset to perform text classification
"""
def __init__(
self,
texts: List[str],
labels: List[str] = None,
label_dict: Mapping[str, int] = None,
max_seq_length: int = 512,
model_name: str = "GroNLP/hateBERT",
):
"""
Args:
texts (List[str]): a list with texts to classify or to train the
classifier on
labels List[str]: a list with classification labels (optional)
label_dict (dict): a dictionary mapping class names to class ids,
to be passed to the validation data (optional)
max_seq_length (int): maximal sequence length in tokens,
texts will be stripped to this length
model_name (str): transformer model name, needed to perform
appropriate tokenization
"""
self.texts = texts
self.labels = labels
self.label_dict = label_dict
self.max_seq_length = max_seq_length
if self.label_dict is None and labels is not None:
# {'class1': 0, 'class2': 1, 'class3': 2, ...}
# no easily handle unknown target values
self.label_dict = dict(zip(sorted(set(labels)), range(len(set(labels)))))
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
# suppresses tokenizer warnings
logging.getLogger("transformers.tokenization_utils").setLevel(logging.FATAL)
def __len__(self) -> int:
"""
Returns:
int: length of the dataset
"""
return len(self.texts)
def __getitem__(self, index) -> Mapping[str, torch.Tensor]:
"""Gets element of the dataset
Args:
index (int): index of the element in the dataset
Returns:
Single element by index
"""
# encoding the text
x = self.texts[index]
# a dictionary with `input_ids` and `attention_mask` as keys
output_dict = self.tokenizer.encode_plus(
x,
add_special_tokens=True,
padding="max_length",
max_length=self.max_seq_length,
return_tensors="pt",
truncation=True,
return_attention_mask=True,
)
# for Catalyst, there needs to be a key called features
output_dict["features"] = output_dict["input_ids"].squeeze(0)
del output_dict["input_ids"]
# encoding target
if self.labels is not None:
y = self.labels[index]
y_encoded = torch.Tensor([self.label_dict.get(y, -1)]).long().squeeze(0)
output_dict["targets"] = y_encoded
return output_dict
What is the problem?
I know questions about similar error have been already asked but they were not of much help in solving this problem.

Keras deep clustering undefined errors in clustering custom layer

i was following this guide to implement a clustering into a deep model
https://ai-mrkogao.github.io/reinforcement%20learning/clusteringkeras/ but i got two errors :
The first one, on this line
clustering_layer = ClusteringLayer(n_clusters, name='clustering')(encoder.output)
it says
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py", line 463, in __call__
self.build(unpack_singleton(input_shapes))
File "<stdin>", line 14, in build
TypeError: add_weight() got multiple values for argument 'name'
So i located
self.clusters = self.add_weight((self.n_clusters, input_dim), initializer='glorot_uniform', name='clusters')
from the class ClusteringLayer and i removed name='clusters' as follow
self.clusters = self.add_weight((self.n_clusters, input_dim), initializer='glorot_uniform')
But now it keeps giving me the following error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py", line 463, in __call__
self.build(unpack_singleton(input_shapes))
File "<stdin>", line 14, in build
File "/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py", line 282, in add_weight
constraint=constraint)
File "/usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py", line 620, in variable
value, dtype=dtype, name=name, constraint=constraint)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py", line 782, in variable
constraint=constraint)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py", line 263, in __call__
return super(VariableMetaclass, cls).__call__(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py", line 460, in __init__
shape=shape)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py", line 582, in _init_from_args
if init_from_fn else [initial_value]) as name:
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py", line 6513, in __enter__
return self._name_scope.__enter__()
File "/usr/lib/python3.6/contextlib.py", line 81, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py", line 4306, in name_scope
if not _VALID_SCOPE_NAME_REGEX.match(name):
TypeError: expected string or bytes-like object
Here is the complete and reproducible code
import keras.backend as K
from keras.engine.topology import Layer, InputSpec
from keras.layers import Dense, Input
from keras.models import Model
from keras.optimizers import SGD
from keras import callbacks
from keras.initializers import VarianceScaling
from sklearn.cluster import KMeans
def autoencoder(dims, act='relu', init='glorot_uniform'):
n_stacks = len(dims) - 1
input_img = Input(shape=(dims[0],), name='input')
x = input_img
for i in range(n_stacks-1):
x = Dense(dims[i + 1], activation=act, kernel_initializer=init, name='encoder_%d' % i)(x)
encoded = Dense(dims[-1], kernel_initializer=init, name='encoder_%d' % (n_stacks - 1))(x) # hidden layer, features are extracted from here
x = encoded
for i in range(n_stacks-1, 0, -1):
x = Dense(dims[i], activation=act, kernel_initializer=init, name='decoder_%d' % i)(x)
x = Dense(dims[0], kernel_initializer=init, name='decoder_0')(x)
decoded = x
return Model(inputs=input_img, outputs=decoded, name='AE'), Model(inputs=input_img, outputs=encoded, name='encoder')
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x = np.concatenate((x_train, x_test))
y = np.concatenate((y_train, y_test))
x = x.reshape((x.shape[0], -1))
x = np.divide(x, 255.)
x_train.shape
x.shape
n_clusters = len(np.unique(y))
kmeans = KMeans(n_clusters=n_clusters, n_init=20, n_jobs=4)
y_pred_kmeans = kmeans.fit_predict(x)
y_pred_kmeans[:10]
dims = [x.shape[-1], 500, 500, 2000, 10]
init = VarianceScaling(scale=1. / 3., mode='fan_in',distribution='uniform')
pretrain_optimizer = SGD(lr=1, momentum=0.9)
autoencoder, encoder = autoencoder(dims, init=init)
autoencoder.compile(optimizer=pretrain_optimizer, loss='mse')
autoencoder.fit(x, x, batch_size=250, epochs=2) #, callbacks=cb)
autoencoder.save_weights( 'ae_weights.h5')
class ClusteringLayer(Layer):
def __init__(self, n_clusters, weights=None, alpha=1.0, **kwargs):
if 'input_shape' not in kwargs and 'input_dim' in kwargs:
kwargs['input_shape'] = (kwargs.pop('input_dim'),)
super(ClusteringLayer, self).__init__(**kwargs)
self.n_clusters = n_clusters
self.alpha = alpha
self.initial_weights = weights
self.input_spec = InputSpec(ndim=2)
def build(self, input_shape):
assert len(input_shape) == 2
input_dim = input_shape[1]
self.input_spec = InputSpec(dtype=K.floatx(), shape=(None, input_dim))
self.clusters = self.add_weight((self.n_clusters, input_dim), initializer='glorot_uniform')
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
self.built = True
def call(self, inputs, **kwargs):
q = 1.0 / (1.0 + (K.sum(K.square(K.expand_dims(inputs, axis=1) - self.clusters), axis=2) / self.alpha))
q **= (self.alpha + 1.0) / 2.0
q = K.transpose(K.transpose(q) / K.sum(q, axis=1)) # Make sure each sample's 10 values add up to 1.
return q
def compute_output_shape(self, input_shape):
assert input_shape and len(input_shape) == 2
return input_shape[0], self.n_clusters
def get_config(self):
config = {'n_clusters': self.n_clusters}
base_config = super(ClusteringLayer, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
clustering_layer = ClusteringLayer(n_clusters, name='clustering')(encoder.output)
model = Model(inputs=encoder.input, outputs=clustering_layer)
model.compile(optimizer=SGD(0.01, 0.9), loss='kld')
model.get_layer(name='clustering').set_weights([kmeans.cluster_centers_])
encoder.output
clustering_layer
784 image input -> 10 classification
The result of
from tensorflow.python import keras
print(keras.__version__)
is
2.2.4-tf
You can even download the docker with keras installation at repbioinfo/autoencoderforclustering
I have solved the error, just correct these line
self.clusters = self.add_weight(shape = (self.n_clusters, input_dim),
initializer='glorot_uniform', name='clusters')
instead of
self.clusters = self.add_weight((self.n_clusters, input_dim), initializer='glorot_uniform')

How to fix TypeError: Caught TypeError in DataLoader worker process 1 in Detectron2

I'm trying to train a Detectron2 model with a COCO dataset. My dataset seems to load correctly. But when I try to train the model using the DefaultTrainer I get
TypeError: Caught TypeError in DataLoader worker process 1.
This is my setup:
from detectron2.engine import DefaultTrainer
# TOTAL_NUM_IMAGES = 10531
cfg = get_cfg()
cfg.OUTPUT_DIR = os.path.join('./output')
cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
cfg.DATASETS.TRAIN = ("my_dataset_train",)
cfg.DATASETS.TEST = ()
cfg.DATALOADER.NUM_WORKERS = 2
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml") # Let training initialize from model zoo
cfg.SOLVER.IMS_PER_BATCH = 2
cfg.SOLVER.BASE_LR = 0.00025 # pick a good LR
# single_iteration = cfg.SOLVER.IMS_PER_BATCH
# iterations_for_one_epoch = TOTAL_NUM_IMAGES / single_iteration
# cfg.SOLVER.MAX_ITER = int(iterations_for_one_epoch) * 20
cfg.SOLVER.STEPS = [] # do not decay learning rate
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1 # only has one class (person). (see https://detectron2.readthedocs.io/tutorials/datasets.html#update-the-config-for-new-datasets)
# NOTE: this config means the number of classes, but a few popular unofficial tutorials incorrect uses num_classes+1 here.
os.makedirs(cfg.OUTPUT_DIR, exist_ok=True)
trainer = DefaultTrainer(cfg)
trainer.resume_or_load(resume=False)
trainer.train()
And I get this error after a couple of iterations:
[01/06 15:14:00 d2.utils.events]: eta: 11:25:20 iter: 125 total_loss: 0.9023 loss_cls: 0.1827 loss_box_reg: 0.1385 loss_mask: 0.5601 loss_rpn_cls: 0.009945 loss_rpn_loc: 0.0023 time: 0.5232 data_time: 0.3085 lr: 3.1219e-05 max_mem: 3271M
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-17-8c48e6e17647> in <module>()
26 trainer = DefaultTrainer(cfg)
27 trainer.resume_or_load(resume=False)
---> 28 trainer.train()
8 frames
/usr/local/lib/python3.7/dist-packages/torch/_utils.py in reraise(self)
432 # instantiate since we don't know how to
433 raise RuntimeError(msg) from None
--> 434 raise exception
435
436
TypeError: Caught TypeError in DataLoader worker process 1.
Original Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/worker.py", line 287, in _worker_loop
data = fetcher.fetch(index)
File "/usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py", line 32, in fetch
data.append(next(self.dataset_iter))
File "/usr/local/lib/python3.7/dist-packages/detectron2/data/common.py", line 201, in __iter__
yield self.dataset[idx]
File "/usr/local/lib/python3.7/dist-packages/detectron2/data/common.py", line 90, in __getitem__
data = self._map_func(self._dataset[cur_idx])
File "/usr/local/lib/python3.7/dist-packages/detectron2/utils/serialize.py", line 26, in __call__
return self._obj(*args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/detectron2/data/dataset_mapper.py", line 189, in __call__
self._transform_annotations(dataset_dict, transforms, image_shape)
File "/usr/local/lib/python3.7/dist-packages/detectron2/data/dataset_mapper.py", line 128, in _transform_annotations
for obj in dataset_dict.pop("annotations")
File "/usr/local/lib/python3.7/dist-packages/detectron2/data/dataset_mapper.py", line 129, in <listcomp>
if obj.get("iscrowd", 0) == 0
File "/usr/local/lib/python3.7/dist-packages/detectron2/data/detection_utils.py", line 297, in transform_instance_annotations
p.reshape(-1) for p in transforms.apply_polygons(polygons)
File "/usr/local/lib/python3.7/dist-packages/fvcore/transforms/transform.py", line 297, in <lambda>
return lambda x: self._apply(x, name)
File "/usr/local/lib/python3.7/dist-packages/fvcore/transforms/transform.py", line 291, in _apply
x = getattr(t, meth)(x)
File "/usr/local/lib/python3.7/dist-packages/fvcore/transforms/transform.py", line 150, in apply_polygons
return [self.apply_coords(p) for p in polygons]
File "/usr/local/lib/python3.7/dist-packages/fvcore/transforms/transform.py", line 150, in <listcomp>
return [self.apply_coords(p) for p in polygons]
File "/usr/local/lib/python3.7/dist-packages/detectron2/data/transforms/transform.py", line 150, in apply_coords
coords[:, 0] = coords[:, 0] * (self.new_w * 1.0 / self.w)
TypeError: can't multiply sequence by non-int of type 'float'
Turns out some of the id's in "annotations" where written in scientific notation resulting in some id's with type float. Converting these to integers solved the problem.

Chainer CNN- TypeError: forward() missing 1 required positional argument: 'x'

I'm trying to run a classifier on Chainer, but failed due to the following error.
I have no idea about the error, because I confirmed that the iterator actually sent a batch to the trainer.
Is there a problem with the neural network model? Or, the way the data has been fed into the model is wrong?
Input.py
from chainer.datasets import split_dataset_random
from chainer.iterators import SerialIterator
from chainer.optimizers import Adam
from chainer.training import Trainer
from chainer.training.updaters import StandardUpdater
from chainer import functions as F, links as L
from chainer import Sequential
import numpy as np
batch_size = 3
X_train = np.ones((9957, 60, 80, 3), dtype=np.float32)
X_train, _ = split_dataset_random(X_train, 8000, seed=0)
train_iter = SerialIterator(X_train, batch_size)
model = Sequential(
L.Convolution2D(None, 64, 3, 2),
F.relu,
L.Convolution2D(64, 32, 3, 2),
F.relu,
L.Linear(None, 16),
F.dropout,
L.Linear(16, 4)
)
model_loss = L.Classifier(model)
optimizer = Adam()
optimizer.setup(model_loss)
updater = StandardUpdater(train_iter, optimizer)
trainer = Trainer(updater, (25, 'epoch'))
trainer.run()
Stacktrace.py
Exception in main training loop: forward() missing 1 required positional argument: 'x'
Traceback (most recent call last):
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/training/trainer.py", line 315, in run
update()
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/training/updaters/standard_updater.py", line 165, in update
self.update_core()
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/training/updaters/standard_updater.py", line 181, in update_core
optimizer.update(loss_func, in_arrays)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/optimizer.py", line 680, in update
loss = lossfun(*args, **kwds)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/link.py", line 242, in __call__
out = forward(*args, **kwargs)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/links/model/classifier.py", line 143, in forward
self.y = self.predictor(*args, **kwargs)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/link.py", line 242, in __call__
out = forward(*args, **kwargs)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/sequential.py", line 210, in forward
x = layer(*x)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/link.py", line 242, in __call__
out = forward(*args, **kwargs)
Will finalize trainer extensions and updater before reraising the exception.
Traceback (most recent call last):
File "/home/user/deploy/aaa.py", line 33, in <module>
trainer.run()
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/training/trainer.py", line 348, in run
six.reraise(*exc_info)
File "/home/user/miniconda3/lib/python3.7/site-packages/six.py", line 693, in reraise
raise value
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/training/trainer.py", line 315, in run
update()
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/training/updaters/standard_updater.py", line 165, in update
self.update_core()
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/training/updaters/standard_updater.py", line 181, in update_core
optimizer.update(loss_func, in_arrays)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/optimizer.py", line 680, in update
loss = lossfun(*args, **kwds)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/link.py", line 242, in __call__
out = forward(*args, **kwargs)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/links/model/classifier.py", line 143, in forward
self.y = self.predictor(*args, **kwargs)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/link.py", line 242, in __call__
out = forward(*args, **kwargs)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/sequential.py", line 210, in forward
x = layer(*x)
File "/home/user/miniconda3/lib/python3.7/site-packages/chainer/link.py", line 242, in __call__
out = forward(*args, **kwargs)
TypeError: forward() missing 1 required positional argument: 'x'
Is there a problem with the neural network model or the way the data has been fed into the model? Please let me know if you need to see the whole code
All you had to do is to give a tuple of ndarray and int to the model, because this is the specification of L.Classifier.
Is there a problem with the neural network model? Or, the way the data has been fed into the model is wrong?
Therefore, the absolute answer is "the way the data has been fed in to the model is wrong".
In the following code, I defined a class inheriting DatasetMixin to feed a tuple of ndarray and int. (This is a conventional way how Chainer goes)
It should be noted that the input argument of L.Convolution2D must be an ndarray whose shape is (batch, channel, width, height). So I transpose the array in the dataset.
Solution.py
from chainer.datasets import split_dataset_random
from chainer.iterators import SerialIterator
from chainer.optimizers import Adam
from chainer.training import Trainer
from chainer.training.updaters import StandardUpdater
from chainer import functions as F, links as L
from chainer import Sequential
from chainer.dataset import DatasetMixin
import numpy as np
class MyDataset(DatasetMixin):
def __init__(self, X, labels):
super(MyDataset, self).__init__()
self.X_ = X
self.labels_ = labels
self.size_ = X.shape[0]
def __len__(self):
return self.size_
def get_example(self, i):
return np.transpose(self.X_[i, ...], (2, 0, 1)), self.labels_[i]
batch_size = 3
X_train = np.ones((9957, 60, 80, 3), dtype=np.float32)
label_train = np.random.randint(0, 4, (9957,), dtype=np.int32)
dataset = MyDataset(X_train, label_train)
dataset_train, _ = split_dataset_random(dataset, 8000, seed=0)
train_iter = SerialIterator(dataset_train, batch_size)
model = Sequential(
L.Convolution2D(None, 64, 3, 2),
F.relu,
L.Convolution2D(64, 32, 3, 2),
F.relu,
L.Linear(None, 16),
F.dropout,
L.Linear(16, 4)
)
model_loss = L.Classifier(model)
optimizer = Adam()
optimizer.setup(model_loss)
updater = StandardUpdater(train_iter, optimizer)
trainer = Trainer(updater, (25, 'epoch'))
trainer.run()

tensorflow graph error when trying to generate data in transfer learning

I'm trying to use transfer learning on the pretrained inception model, so I created a class for feature extraction from the model:
from prototype import Dataset, VideoStreamHandler
import numpy
import random
from keras.applications.inception_v3 import preprocess_input
from keras.preprocessing import image
from scipy.misc import imresize
import time
class Extractor(Dataset.Dataset):
"""
"""
def __init__(self, path_to_data, seq_len, base_model, image_shape=(299, 299, 3)):
super().__init__(path_to_data, seq_len, input_shape=image_shape)
self._extractor = base_model
def extract_features(self, batch_size):
"""
passes the data through the base model to get the feature map to later train on
:return: feature map
"""
class_one_hot = self.one_hot_encode() # get the one hot for the classes
data = self.clean_data(self.get_data(), self._input_shape[0])
print("Processing {} videos".format(len(self.get_data())))
transfer_maps, labels = [], []
rand = random.SystemRandom()
while True:
for _ in range(batch_size):
row = rand.choice(data)
sequence = self.get_frames(row[0])
if len(sequence) > self._input_shape[0]:
sequence = self.rescale_frame_list(sequence, self._input_shape[0])
print("{} video processing is complete".format(row[0].split('\\')[-1]))
features = []
for frame in sequence:
frame_arr = image.img_to_array(frame) # turn image to numpy array
frame_arr = numpy.expand_dims(frame_arr, axis=0)
frame_arr = preprocess_input(frame_arr)
features.append(self._extractor.predict(frame_arr))
transfer_maps.append(features)
labels.append(class_one_hot[row[1]])
yield numpy.array(transfer_maps), numpy.array(labels)
def get_frames(self, pth):
"""
:type: string
:param pth: path to the specific file from which we take the frames
:return: the frames in the file
"""
f_queue = VideoStreamHandler.VideoStream(pth) # This object opens a thread that reads frames with opencv
# capture independently from the frame processing to prevent i/o delay and speed up processing
f_queue.start()
time.sleep(1.0) # wait a moment so the thread could start reading frames
sequence = []
while f_queue.isnt_empty():
frame = f_queue.read()
# resize is used to keep all frames from all videos the same size
frame = imresize(frame, (self._input_shape[1], self._input_shape[2]))
sequence.append(frame)
f_queue.close() # close the thread
return sequence
Then, I attempt to train a new model with keras's fit_generator:
my_model.fit_generator(generator=train_gen, epochs=10, steps_per_epoch=steps_per_epoch, verbose=1, workers=4)
However, I get this error:
Blockquote
Traceback (most recent call last):
File "C:/Users/Aviad Lazar/Desktop/project/prototype/transfer_learning.py", line 41, in
main()
File "C:/Users/Aviad Lazar/Desktop/project/prototype/transfer_learning.py", line 34, in main
my_model.fit_generator(generator=train_gen, epochs=10, steps_per_epoch=steps_per_epoch, verbose=1, workers=4)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\legacy\interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\models.py", line 1315, in fit_generator
initial_epoch=initial_epoch)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\legacy\interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\engine\training.py", line 2194, in fit_generator
generator_output = next(output_generator)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\utils\data_utils.py", line 793, in get
six.reraise(value.class, value, value.traceback)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\six.py", line 693, in reraise
raise value
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\utils\data_utils.py", line 658, in _data_generator_task
generator_output = next(self._generator)
File "C:\Users\Aviad Lazar\Desktop\project\prototype\FeatureExtractor.py", line 48, in extract_features
features.append(self._extractor.predict(frame_arr))
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\engine\training.py", line 1832, in predict
self._make_predict_function()
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\engine\training.py", line 1031, in _make_predict_function
**kwargs)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\backend\tensorflow_backend.py", line 2506, in function
return Function(inputs, outputs, updates=updates, **kwargs)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\keras\backend\tensorflow_backend.py", line 2449, in init
with tf.control_dependencies(self.outputs):
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\tensorflow\python\framework\ops.py", line 4863, in control_dependencies
return get_default_graph().control_dependencies(control_inputs)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\tensorflow\python\framework\ops.py", line 4481, in control_dependencies
c = self.as_graph_element(c)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\tensorflow\python\framework\ops.py", line 3478, in as_graph_element
return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
File "C:\Users\Aviad Lazar\Desktop\project\venv\lib\site-packages\tensorflow\python\framework\ops.py", line 3557, in _as_graph_element_locked
raise ValueError("Tensor %s is not an element of this graph." % obj)
ValueError: Tensor Tensor("global_average_pooling2d_1/Mean:0", shape=(?, 2048), dtype=float32) is not an element of this graph.

Resources