I've been working on this Segformer (using transformers for image segmentation) I've been having issues with getting a message stating that the target is out of bounds.
So here is the code that I am using.
!pip install --upgrade transformers
!nvidia-smi
from torch.utils.data import Dataset, DataLoader
from transformers import AdamW
import torch
from torch import nn
from sklearn.metrics import accuracy_score
from tqdm.notebook import tqdm
import os
from PIL import Image
from transformers import SegformerForSemanticSegmentation,
SegformerFeatureExtractor
import pandas as pd
import cv2
import numpy as np
import albumentations as aug
os.getcwd()
ok, from here this is my current working directoy:
'/data/users/me/Rugd_dataset'
My images are stored in two folders one called images, the nest mask. Each have a sub directory of test and train
WIDTH = 512
Height = 512
class ImageSegmentationDataset(Dataset):
"""Image segmentation dataset."""
def __init__(self, root_dir, feature_extractor, transforms=None, train=True):
"""
Args:
root_dir (string): Root directory of the dataset containing the images + annotations.
feature_extractor (SegFormerFeatureExtractor): feature extractor to prepare images + segmentation maps.
train (bool): Whether to load "training" or "validation" images + annotations.
"""
self.root_dir = root_dir
self.feature_extractor = feature_extractor
self.train = train
self.transforms = transforms
sub_path = "train" if self.train else "test"
self.img_dir = os.path.join(self.root_dir, "images", sub_path)
self.ann_dir = os.path.join(self.root_dir, "mask", sub_path)
# read images
image_file_names = []
for root, dirs, files in os.walk(self.img_dir):
image_file_names.extend(files)
self.images = sorted(image_file_names)
# read annotations
annotation_file_names = []
for root, dirs, files in os.walk(self.ann_dir):
annotation_file_names.extend(files)
self.annotations = sorted(annotation_file_names)
assert len(self.images) == len(self.annotations), "There must be as many images as there are segmentation maps"
def __len__(self):
return len(self.images)
def __getitem__(self, idx):
image = cv2.imread(os.path.join(self.img_dir,
self.images[idx]))
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
segmentation_map = cv2.imread(os.path.join(self.ann_dir, self.annotations[idx]))
segmentation_map = cv2.cvtColor(segmentation_map, cv2.COLOR_BGR2GRAY)
# image = Image.open()
# segmentation_map = Image.open()
if self.transforms is not None:
augmented = self.transforms(image=image, mask=segmentation_map)
# randomly crop + pad both image and segmentation map to same size
encoded_inputs = self.feature_extractor(augmented['image'], augmented['mask'], return_tensors="pt")
else:
encoded_inputs = self.feature_extractor(image, segmentation_map, return_tensors="pt")
for k,v in encoded_inputs.items():
encoded_inputs[k].squeeze_() # remove batch dimension
return encoded_inputs
transform = aug.Compose([
aug.Flip(p=0.5)
])
dir_path = r'images/train'
count = 0
# Iterate directory
for path in os.listdir(dir_path):
# check if current path is a file
if os.path.isfile(os.path.join(dir_path, path)):
count += 1
print('File count:', count)
current count = File count: 7386
dir_path = r'mask/train'
count = 0
# Iterate directory
for path in os.listdir(dir_path):
# check if current path is a file
if os.path.isfile(os.path.join(dir_path, path)):
count += 1
print('File count:', count)
this is what I receive as a File count: 7386. So my paths to the images seem to fit.
root_dir = '/data/users/christopher.kehl/Rugd_dataset'
feature_extractor = SegformerFeatureExtractor(align=False, reduce_zero_label=False)
train_dataset = ImageSegmentationDataset(root_dir=root_dir, feature_extractor=feature_extractor, transforms=transform)
valid_dataset = ImageSegmentationDataset(root_dir=root_dir, feature_extractor=feature_extractor, transforms=None, train=False)
print("Number of training examples:", len(train_dataset))
print("Number of validation examples:", len(valid_dataset))
Number of training examples: 7387
Number of validation examples: 100
encoded_inputs = train_dataset[-1]
so the index here is supposed to be zero, but I can only get this to work with a 1 or an -1, anything other than 0.
encoded_inputs["pixel_values"].shape
torch.Size([3, 512, 512])
encoded_inputs["labels"].shape
torch.Size([512, 512])
encoded_inputs["labels"].shape
torch.Size([512, 512])
encoded_inputs["labels"].squeeze().unique()
tensor([ 29, 60, 76, 91, 107])
mask = encoded_inputs["labels"].numpy()
import matplotlib.pyplot as plt
plt.imshow(mask)
shows the images of a mask
from torch.utils.data import DataLoader
train_dataloader = DataLoader(train_dataset, batch_size=4, shuffle=True)
valid_dataloader = DataLoader(valid_dataset, batch_size=4)
batch = next(iter(train_dataloader))
for k,v in batch.items():
print(k, v.shape)
pixel_values torch.Size([4, 3, 512, 512])
labels torch.Size([4, 512, 512])
batch["labels"].shape
torch.Size([4, 512, 512])
classes = pd.read_csv('class_dict_seg.csv')['name']
id2label = classes.to_dict()
label2id = {v: k for k, v in id2label.items()}
model = SegformerForSemanticSegmentation.from_pretrained("nvidia/mit-b5", ignore_mismatched_sizes=True,
num_labels=len(id2label), id2label=id2label, label2id=label2id,
reshape_last_stage=True)
optimizer = AdamW(model.parameters(), lr=0.00006)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
print("Model Initialized!")
for epoch in range(1, 11): # loop over the dataset multiple times
print("Epoch:", epoch)
pbar = tqdm(train_dataloader)
accuracies = []
losses = []
val_accuracies = []
val_losses = []
model.train()
for idx, batch in enumerate(pbar):
# get the inputs;
pixel_values = batch["pixel_values"].to(device)
labels = batch["labels"].to(device)
# zero the parameter gradients
optimizer.zero_grad()
# forward
outputs = model(pixel_values=pixel_values, labels=labels)
# evaluate
upsampled_logits = nn.functional.interpolate(outputs.logits, size=labels.shape[-2:], mode="bilinear", align_corners=False)
predicted = upsampled_logits.argmax(dim=1)
mask = (labels != 255) # we don't include the background class in the accuracy calculation
pred_labels = predicted[mask].detach().cpu().numpy()
true_labels = labels[mask].detach().cpu().numpy()
accuracy = accuracy_score(pred_labels, true_labels)
loss = outputs.loss
accuracies.append(accuracy)
losses.append(loss.item())
pbar.set_postfix({'Batch': idx, 'Pixel-wise accuracy': sum(accuracies)/len(accuracies), 'Loss': sum(losses)/len(losses)})
# backward + optimize
loss.backward()
optimizer.step()
else:
model.eval()
with torch.no_grad():
for idx, batch in enumerate(valid_dataloader):
pixel_values = batch["pixel_values"].to(device)
labels = batch["labels"].to(device)
outputs = model(pixel_values=pixel_values, labels=labels)
upsampled_logits = nn.functional.interpolate(outputs.logits, size=labels.shape[-2:], mode="bilinear", align_corners=False)
predicted = upsampled_logits.argmax(dim=1)
mask = (labels != 255) # we don't include the background class in the accuracy calculation
pred_labels = predicted[mask].detach().cpu().numpy()
true_labels = labels[mask].detach().cpu().numpy()
accuracy = accuracy_score(pred_labels, true_labels)
val_loss = outputs.loss
val_accuracies.append(accuracy)
val_losses.append(val_loss.item())
print(f"Train Pixel-wise accuracy: {sum(accuracies)/len(accuracies)}\
Train Loss: {sum(losses)/len(losses)}\
Val Pixel-wise accuracy: {sum(val_accuracies)/len(val_accuracies)}\
Val Loss: {sum(val_losses)/len(val_losses)}")
Here is the error Block:
IndexError: Target 151 is out of bounds.
Full Trace
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-32-50d0deee01ff> in <module>
16
17 # forward
---> 18 outputs = model(pixel_values=pixel_values, labels=labels)
19
20 # evaluate
~/.local/lib/python3.6/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1101 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102 return forward_call(*input, **kwargs)
1103 # Do not call functions when jit is used
1104 full_backward_hooks, non_full_backward_hooks = [], []
~/.local/lib/python3.6/site-packages/transformers/models/segformer/modeling_segformer.py in forward(self, pixel_values, labels, output_attentions, output_hidden_states, return_dict)
807 )
808 loss_fct = CrossEntropyLoss(ignore_index=self.config.semantic_loss_ignore_index)
--> 809 loss = loss_fct(upsampled_logits, labels)
810
811 if not return_dict:
~/.local/lib/python3.6/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1101 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102 return forward_call(*input, **kwargs)
1103 # Do not call functions when jit is used
1104 full_backward_hooks, non_full_backward_hooks = [], []
~/.local/lib/python3.6/site-packages/torch/nn/modules/loss.py in forward(self, input, target)
1150 return F.cross_entropy(input, target, weight=self.weight,
1151 ignore_index=self.ignore_index, reduction=self.reduction,
-> 1152 label_smoothing=self.label_smoothing)
1153
1154
~/.local/lib/python3.6/site-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction, label_smoothing)
2844 if size_average is not None or reduce is not None:
2845 reduction = _Reduction.legacy_get_string(size_average, reduce)
-> 2846 return torch._C._nn.cross_entropy_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index, label_smoothing)
2847
2848
IndexError: Target 150 is out of bounds.
Related
I am beginning to learn how to develop CNN models using PyTorch, and I am currently working on a local dataset that has feature size of 1x4 and a binary label. I am also implementing K-Fold Cross Validation in the process. I have been able to develop a previous CNN model with a different dataset and procedure, but I am currently receiving and error in the code. I would appreciate your help, as I have been stuck in this error for a few days now.
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In [34], line 12
9 test_loader = DataLoader(dataset, sampler=test_sampler)
11 for epoch in range(num_epochs):
---> 12 train_loss,train_correct = train_epoch(model,train_loader,criterion,optimizer)
13 test_loss,test_correct = test_epoch(model,test_loader,criterion)
15 train_loss = train_loss/len(train_loader.sampler)
Cell In [33], line 11, in train_epoch(model, dataloader, loss_fn, optimizer)
9 #Forward Pass
10 print(features)
---> 11 output=model(features)
12 loss=loss_fn(output,labels)
14 #Backward Pass
File ~\Anaconda\Installation\envs\FYP\lib\site-packages\torch\nn\modules\module.py:1480, in Module._call_impl(self, *args, **kwargs)
1475 # If we don't have any hooks, we want to skip the rest of the logic in
1476 # this function, and just call forward.
1477 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
1478 or _global_backward_pre_hooks or _global_backward_hooks
1479 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1480 return forward_call(*args, **kwargs)
1481 # Do not call functions when jit is used
1482 full_backward_hooks, non_full_backward_hooks = [], []
Cell In [31], line 14, in ConvNet.forward(self, x)
12 def forward(self,x):
13 print(x)
---> 14 print(self.conv1(x))
15 x = F.relu(F.max_pool2d(self.conv1(x), kernel_size=2))
16 x = F.relu(F.max_pool2d(self.conv2(x), kernel_size=2))
File ~\Anaconda\Installation\envs\FYP\lib\site-packages\torch\nn\modules\module.py:1480, in Module._call_impl(self, *args, **kwargs)
1475 # If we don't have any hooks, we want to skip the rest of the logic in
1476 # this function, and just call forward.
1477 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
1478 or _global_backward_pre_hooks or _global_backward_hooks
1479 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1480 return forward_call(*args, **kwargs)
1481 # Do not call functions when jit is used
1482 full_backward_hooks, non_full_backward_hooks = [], []
File ~\Anaconda\Installation\envs\FYP\lib\site-packages\torch\nn\modules\conv.py:463, in Conv2d.forward(self, input)
462 def forward(self, input: Tensor) -> Tensor:
--> 463 return self._conv_forward(input, self.weight, self.bias)
File ~\Anaconda\Installation\envs\FYP\lib\site-packages\torch\nn\modules\conv.py:459, in Conv2d._conv_forward(self, input, weight, bias)
455 if self.padding_mode != 'zeros':
456 return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode),
457 weight, bias, self.stride,
458 _pair(0), self.dilation, self.groups)
--> 459 return F.conv2d(input, weight, bias, self.stride,
460 self.padding, self.dilation, self.groups)
RuntimeError: Expected 3D (unbatched) or 4D (batched) input to conv2d, but got input of size: [1, 4]
This is my current code for your reference.
## Importing Packages
import torch
import torch.nn as nn #To use neural network related functions (creating layers,)
import torch.nn.functional as F #To use certain activation functions
from torch.utils.data import Dataset, DataLoader, random_split, SubsetRandomSampler, TensorDataset, ConcatDataset
import torchvision #To use certain datasets (MNIST, CIFAR10), apply transformations to datasets
from torchvision import datasets, transforms
import numpy as np
from sklearn.model_selection import KFold, train_test_split
import pandas as pd
## Importing the Dataset
raw_dataset = pd.read_excel(r'C:\Users\Family\Desktop\Nottingham\Year 4\FYP\Software\Datasets\Original\CEA Classification Dataset.xlsx', sheet_name='Sheet1')
dataset = raw_dataset.drop(columns=raw_dataset.columns[0])
X = dataset.drop('Target',axis=1)
y = dataset['Target'].values
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.2, random_state=42)
train_data = TensorDataset(torch.tensor(X_train.values,dtype=torch.float32), torch.tensor(y_train,dtype=torch.float32))
test_data = TensorDataset(torch.tensor(X_test.values,dtype=torch.float32), torch.tensor(y_test,dtype=torch.float32))
dataset = ConcatDataset([train_data,test_data])
## Creating Convolutional Model
# Creating Model class
class ConvNet(nn.Module):
def __init__(self,h1=96):
super(ConvNet,self).__init__()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, stride=1, padding=2)
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1, padding=2)
self.drop1 = nn.Dropout2d(p=0.5)
self.fc1 = nn.Linear(32*7*7,h1)
self.drop2 = nn.Dropout2d(p=0.1)
self.fc2 = nn.Linear(h1,2)
def forward(self,x):
print(x)
print(self.conv1(x))
x = F.relu(F.max_pool2d(self.conv1(x), kernel_size=2))
x = F.relu(F.max_pool2d(self.conv2(x), kernel_size=2))
x = self.drop1(x)
x = x.view(x.size(0),-1)
x = F.relu(self.fc1(x))
x = self.drop2(x)
x = self.fc2(x)
return x
## Defining Hyper-parameters, K Fold, and Model configuration
# Hyper-parameters
num_epochs = 4
learning_rate = 0.001
batch_size=128
# K Fold
k = 10
splits = KFold(n_splits=k, shuffle=True, random_state=42)
foldperf={}
# Model, Loss Function, Optimizer
model = ConvNet()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
## Training & Testing Loop Functions
def train_epoch(model,dataloader,loss_fn,optimizer):
train_loss,train_correct = 0.0, 0
model.train() #Sets the mode to train (Helpful when using layers such as DropOut and BatchNorm)
for features,labels in dataloader:
#Zero grad
optimizer.zero_grad()
#Forward Pass
print(features)
output=model(features)
loss=loss_fn(output,labels)
#Backward Pass
loss.backward()
optimizer.step()
train_loss += loss.item()*features.size(0)
print(loss.item,features.size(0))
scores, predictions = torch.max(output.data,1) # 1 is to create a 1 dimensional tensor with max values from each row
train_correct += (predictions==labels).sum().item()
return train_loss, train_correct
def test_epoch(model,dataloader,loss_fn):
test_loss, test_correct = 0.0, 0
model.eval()
for features, labels in dataloader:
output = model(features)
loss = loss_fn(output,labels)
test_loss += loss.item()*features.size(0)
scores, predictions = torch.max(output.data,1)
test_correct += (predictions==labels).sum().item()
return test_loss, test_correct
history = {'train_loss': [], 'test_loss': [], 'train_acc': [], 'test_acc': []}
for fold, (train_idx,test_idx) in enumerate(splits.split(np.arange(len(dataset)))):
print('Fold {}'.format(fold+1))
train_sampler = SubsetRandomSampler(train_idx)
test_sampler = SubsetRandomSampler(test_idx)
train_loader = DataLoader(dataset, sampler=train_sampler)
test_loader = DataLoader(dataset, sampler=test_sampler)
for epoch in range(num_epochs):
train_loss,train_correct = train_epoch(model,train_loader,criterion,optimizer)
test_loss,test_correct = test_epoch(model,test_loader,criterion)
train_loss = train_loss/len(train_loader.sampler)
train_acc = train_correct//len(train_loader.sampler)*100
test_loss = test_loss/len(test_loader.sampler)
test_acc = test_correct//len(test_loader.sampler)*100
print("Epoch:{}/{} AVG Training Loss: {:.3f} AVG Test Loss: {:.3f} AVG Training Acc: {:.2f}% AVG Test Acc: {:.2f}%"
.format(epoch+1, num_epochs, train_loss, test_loss, train_acc, test_acc))
history['train_loss'.append(train_loss)]
history['test_loss'.append(test_loss)]
history['train_acc'.append(train_acc)]
history['test_acc'.append(test_acc)]
Thank you for your help.
I am trying to extract key value pair from scanned invoices document using LayoutLMV2 model but I am getting error. Installation guide. I am just trying to check how the model is predicting the key value pair from the document or do I need to fine tune the model in own data set. Need help in this.
from transformers import PreTrainedTokenizerBase, LayoutLMv2FeatureExtractor, LayoutLMv2Processor, AutoTokenizer, LayoutLMv2ForRelationExtraction, AdamW
from transformers.file_utils import PaddingStrategy
import torch
from torch import nn
from dataclasses import dataclass
from typing import Dict, Tuple, Optional, Union
from datasets import load_dataset
from torch.utils.data import DataLoader
from torchvision.transforms import ToPILImage
from torchvision import transforms
from PIL import Image, ImageFont, ImageDraw, ImageEnhance, ImageFilter
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Users\name\AppData\Local\Programs\Tesseract-OCR\tesseract.exe'
feature_extractor = LayoutLMv2FeatureExtractor(apply_ocr=True)
tokenizer = AutoTokenizer.from_pretrained(path_1, pad_token='<pad>')
processor = LayoutLMv2Processor(feature_extractor, tokenizer)
model = LayoutLMv2ForRelationExtraction.from_pretrained(path_1)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
image_file = 'image2.png'
image = Image.open(image_file).convert('RGB')
image.size
encoded_inputs = processor(image, return_tensors="pt")
encoded_inputs.keys()
for k,v in encoded_inputs.items():
print(k, v.shape)
for k,v in encoded_inputs.items():
encoded_inputs[k] = v.to(model.device)
# forward pass
outputs = model(**encoded_inputs)
This is the error I am getting
TypeError Traceback (most recent call last)
c:\Users\name\Parallel Project\Trans_LayoutXLM.ipynb Cell 7 in <cell line: 5>()
2 encoded_inputs[k] = v.to(model.device)
4 # forward pass
----> 5 outputs = model(**encoded_inputs)
File c:\Users\name\.conda\envs\layoutlmft\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
1126 # If we don't have any hooks, we want to skip the rest of the logic in
1127 # this function, and just call forward.
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1129 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130 return forward_call(*input, **kwargs)
1131 # Do not call functions when jit is used
1132 full_backward_hooks, non_full_backward_hooks = [], []
File c:\Users\name\.conda\envs\layoutlmft\lib\site-packages\transformers\models\layoutlmv2\modeling_layoutlmv2.py:1598, in LayoutLMv2ForRelationExtraction.forward(self, input_ids, bbox, labels, image, attention_mask, token_type_ids, position_ids, head_mask, entities, relations)
1596 sequence_output, image_output = outputs[0][:, :seq_length], outputs[0][:, seq_length:]
1597 sequence_output = self.dropout(sequence_output)
-> 1598 loss, pred_relations = self.extractor(sequence_output, entities, relations)
1600 return RegionExtractionOutput(
1601 loss=loss,
1602 entities=entities,
(...)
1605 hidden_states=outputs[0],
1606 )
File c:\Users\name\.conda\envs\layoutlmft\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
1126 # If we don't have any hooks, we want to skip the rest of the logic in
1127 # this function, and just call forward.
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1129 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130 return forward_call(*input, **kwargs)
1131 # Do not call functions when jit is used
1132 full_backward_hooks, non_full_backward_hooks = [], []
...
-> 1421 batch_size = len(relations)
1422 new_relations = []
1423 for b in range(batch_size):
TypeError: object of type 'NoneType' has no len()
import numpy as np
from transformers import LayoutLMv2Processor, LayoutLMv2ForTokenClassification
from datasets import load_dataset
from PIL import Image, ImageDraw, ImageFont
processor = LayoutLMv2Processor.from_pretrained("microsoft/layoutlmv2-base-uncased")
model = LayoutLMv2ForTokenClassification.from_pretrained("nielsr/layoutlmv2-finetuned-funsd")
dataset = load_dataset("nielsr/funsd", split="test")
labels = dataset.features['ner_tags'].feature.names
id2label = {v: k for v, k in enumerate(labels)}
label2color = {'question':'blue', 'answer':'green', 'header':'orange', 'other':'red'}
def unnormalize_box(bbox, width, height):
return [
width * (bbox[0] / 1000),
height * (bbox[1] / 1000),
width * (bbox[2] / 1000),
height * (bbox[3] / 1000),
]
def iob_to_label(label):
label = label[2:]
if not label:
return 'other'
return label
image_path="invoice.jpg"
# load image example
image = Image.open(image_path).convert("RGB")
image
def process_image(image):
width, height = image.size
# encode
encoding = processor(image, truncation=True, return_offsets_mapping=True, return_tensors="pt")
offset_mapping = encoding.pop('offset_mapping')
# forward pass
outputs = model(**encoding)
# get predictions
predictions = outputs.logits.argmax(-1).squeeze().tolist()
token_boxes = encoding.bbox.squeeze().tolist()
# only keep non-subword predictions
is_subword = np.array(offset_mapping.squeeze().tolist())[:,0] != 0
true_predictions = [id2label[pred] for idx, pred in enumerate(predictions) if not is_subword[idx]]
true_boxes = [unnormalize_box(box, width, height) for idx, box in enumerate(token_boxes) if not is_subword[idx]]
# draw predictions over the image
draw = ImageDraw.Draw(image)
font = ImageFont.load_default()
for prediction, box in zip(true_predictions, true_boxes):
predicted_label = iob_to_label(prediction).lower()
draw.rectangle(box, outline=label2color[predicted_label])
draw.text((box[0]+10, box[1]-10), text=predicted_label, fill=label2color[predicted_label], font=font)
return image
process_image(image)
I tried to write a segmentation model, i am quite new to the topic and i got to the dead spot.
From what i tried to debug, i think that the shape of my mask batches does not match the size of the predicted batches and therefore i got the following error:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-84-abd99309752a> in <module>()
3 for i in range(EPOCHS):
4 #train_loss = train_func(trainloader,model,optimizer)
----> 5 valid_loss = eval_func(validloader,model)
6
7 if valid_loss <best_loss:
4 frames
<ipython-input-82-328c759ec537> in eval_func(dataloader, model)
6 images = images.to(DEVICE)
7 masks = mask.to(DEVICE)
----> 8 logits, loss = model(images,masks)
9 total_loss += loss.item()
10 return total_loss / len(dataloader)
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1109 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1110 return forward_call(*input, **kwargs)
1111 # Do not call functions when jit is used
1112 full_backward_hooks, non_full_backward_hooks = [], []
<ipython-input-79-567e281ae719> in forward(self, images, masks)
15 if mask != None:
16 print(logits.size)
---> 17 return logits, lossF(logits,masks)
18 return logits
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1109 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1110 return forward_call(*input, **kwargs)
1111 # Do not call functions when jit is used
1112 full_backward_hooks, non_full_backward_hooks = [], []
/usr/local/lib/python3.7/dist-packages/segmentation_models_pytorch/losses/dice.py in forward(self, y_pred, y_true)
58 def forward(self, y_pred: torch.Tensor, y_true: torch.Tensor) -> torch.Tensor:
59
---> 60 assert y_true.size(0) == y_pred.size(0)
61
62 if self.from_logits:
AssertionError:
I have no clue how to fix the error in code. I tried few adjustments in the SegmentationDataset, but it did not help. You can find relevant (to my mind) part of the code below.
import albumentations as A
def get_train_augs():
return A.Compose([
#A.Resize(IMG_SIZE,IMG_SIZE, interpolation = cv2.INTER_LINEAR),
A.RandomCrop(width=IMG_SIZE, height=IMG_SIZE),
A.HorizontalFlip(p=0.5),
A.RandomBrightnessContrast(p=.75)
])
def get_val_augs():
return A.Compose([
A.RandomCrop(width=IMG_SIZE, height=IMG_SIZE),
])
class SegmentationDataset(Dataset):
def __init__(self,df,augumentations):
self.df = df
self.augumentations = augumentations
def __len__(self):
return len(self.df)
def __getitem__(self,idx):
row = self.df.iloc [idx]
image_path = row.Images
mask_path = row.Masks
image = cv2.imread(image_path)
image = cv2.cvtColor(np.float32(image), cv2.COLOR_BGR2RGB)
mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)
mask = (mask==33)*1 + (mask==79)*1
mask = (mask>0)*1
mask = np.expand_dims(mask, axis=-1)
if self.augumentations:
data = self.augumentations(image = image, mask = mask)
image = data['image']
mask = data['mask']
image = np.transpose(image, (2,0,1)).astype(np.float32)
mask = np.transpose(mask, (2,0,1)).astype(np.float32)
image = torch.Tensor(image)/255.0
mask = torch.Tensor(mask)
mask = torch.round(torch.Tensor(mask))
return image, mask
class SegmentationModel(nn.Module):
def __init__(self):
super(SegmentationModel,self).__init__()
self.backbone = smp.Unet(
encoder_name=ENCODER,
encoder_weights=WEIGHTS,
in_channels =3,
classes = 1,
activation=None
)
def forward(self,images, masks= None):
logits = self.backbone(images)
lossF = DiceLoss(mode = 'binary')
if mask != None:
return logits, lossF(logits,masks)
return logits
def train_func(dataloader, model,optimizer):
model.train()
total_loss = 0.0
for images, masks in tqdm(dataloader):
images = images.to(DEVICE)
masks = mask.to(DEVICE)
optimizer.zero_grad()
logits, loss = model(images,masks)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(mask.size)
return total_loss / len(dataloader)
train_loss = train_func(trainloader,model,optimizer)
def eval_func(dataloader, model):
model.eval()
total_loss = 0.0
with torch.no_grad():
for images, masks in tqdm(dataloader):
images = images.to(DEVICE)
masks = mask.to(DEVICE)
logits, loss = model(images,masks)
total_loss += loss.item()
return total_loss / len(dataloader)
Train_Images = os.listdir(os.path.join(os.getcwd(), 'uavid_train/Images'))
for k in range(0,len(Train_Images)): Train_Images[k] = 'uavid_train/Images/' + Train_Images[k]
Train_Labels = os.listdir(os.path.join(os.getcwd(), 'uavid_train/Labels'))
for k in range(0,len(Train_Labels)): Train_Labels[k] = 'uavid_train/Labels/' + Train_Labels[k]
Train_DF = pd.DataFrame([Train_Images, Train_Labels]).T
Train_DF.columns = ['Images', 'Masks']
Val_Images = os.listdir(os.path.join(os.getcwd(), 'uavid_val/Images'))
for k in range(0,len(Val_Images)): Val_Images[k] = 'uavid_val/Images/' + Val_Images[k]
Val_Labels = os.listdir(os.path.join(os.getcwd(), 'uavid_val/Labels'))
for k in range(0,len(Val_Labels)): Val_Labels[k] = 'uavid_val/Labels/' + Val_Labels[k]
Val_DF = pd.DataFrame([ Val_Images, Val_Labels]).T
Val_DF.columns = ['Images', 'Masks']
trainloader = DataLoader(trainset, batch_size=BATCH_SIZE, shuffle=True)
validloader = DataLoader(valset, batch_size=len(valset))
model = SegmentationModel()
model.to(DEVICE)
optimizer = torch.optim.Adam(model.parameters(), lr = LR)
best_loss = np.Inf
for i in range(EPOCHS):
#train_loss = train_func(trainloader,model,optimizer)
valid_loss = eval_func(validloader,model)
if valid_loss <best_loss:
torch.save(model.state_dict(),"best-model.pt")
print('SAVED')
best_loss = valid_loss
print(f"Epoch : {i+1} Train Loss : {train_loss} Valid Loss : {valid_loss}")
What you have to do is to convert your mask into one-hot-encoded version and then convert it into a single channel. Let's say you have 3-classes in you your mask that are described by 3 colors: [255,0,0], [0,255,0], [0,0,255]. And your input mask is standard RGB image. You can write a function that converts it into the desired format like this:
def convert_mask(rgb_mask):
colormaps = [[255,0,0], [0,255,0], [0,0,255]]
output_mask = list()
for colormap in colormaps:
cmap = np.all(np.equal(mask, colormap), axis=-1)
output_mask.append(cmap)
m = np.stack(output_mask, axis=-1) # one hot mask
m = np.argmax(m, axis=-1) # single channel mask
return m
This function should return a (N,1,H,W) mask that should work during trainig.
Hope it helps.
I am trying to use the Pytorch-geometric hypergraph convolution network's layer for training no hypergraph. I am using the Amazon review dataset provided by https://www.cs.cornell.edu/~arb/data/amazon-reviews/
Since a node doesn't have a feature, I merely put constants in all nodes as features. Further for hyperedges, I construct an incidence matrix.
First, download the dataset using the command:
!wget -P /tmp https://github.com/gravitogen/hosting_datasets/releases/download/amazon_review_1.0/amazon-reviews.zip
!unzip /tmp/amazon-reviews.zip
Code is below:
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch_geometric.nn import HypergraphConv
import numpy as np
import pandas as pd
class HyperGraph1(nn.Module):
def __init__(self, nfeatures, nhiddden, nclass, dropout,nlayer=1):
super(HyperGraph1, self).__init__()
self.conv1 = HypergraphConv(nfeatures, 16)
self.conv2 = HypergraphConv(16,nclass)
self.dropout_p = dropout
def forward(self, data):
x, edge_index = data.x, data.edge_index
x = self.conv1(x, edge_index)
x = F.relu(x)
x = F.dropout(x, training=self.training)
x = self.conv2(x, edge_index)
return F.log_softmax(x, dim=1)
folder = 'amazon-reviews/'
node_indices_files = 'node-labels-amazon-reviews.txt'
node_label_files = 'label-names-amazon-reviews.txt'
hyperedge_files = 'hyperedges-amazon-reviews.txt'
node_indices = pd.read_csv(folder + node_indices_files, header=None)
labels_annot = pd.read_csv(folder + node_label_files, header = None)
hyper_edge = []
with open(folder + hyperedge_files) as f:
for line in f.readlines():
chunks = line.split(',')
chunks = [int(i) for i in chunks]
hyper_edge.append(chunks)
nodes = node_indices.index.to_list()
labels = node_indices[node_indices.columns[0]].to_list()
# generating sparse incidence matrix for storing hyperedges
node_on_edge_list = []
edge_indices = []
counter = 0
for l in hyper_edge:
node_on_edge_list += l
edge_indices += [counter]*len(l)
counter = counter + 1
hyperedge_index = torch.tensor([ node_on_edge_list, edge_indices])
# generate `Data` for pytorch-geometric
x = np.zeros(len(nodes)*2, dtype=int)
x = x.reshape(len(nodes),2).tolist()
X = torch.tensor(x, dtype=torch.float)
Y = torch.tensor(labels, dtype=torch.int)
from torch_geometric.data import Data
data = Data(x=X, edge_index=hyperedge_index, y=Y)
# Now get ready for training
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = HyperGraph1(nfeatures=2, nhiddden=16, nclass=labels_annot.shape[0],dropout=0.1).to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
model.train()
random_nums = np.random.rand(1, len(data.y))
train_np = random_nums > 0.5
train_mask = train_np.tolist()[0]
test_np = random_nums <= 0.5
test_mask = test_np.tolist()[0]
data.train_mask = torch.tensor(train_mask)
data.test_mask = torch.tensor(test_mask)
for epoch in range(2000):
optimizer.zero_grad()
out = model(data)
loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
However, upon attempt to train the network, I get the following error:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-98-40e1b6f967df> in <module>
1 for epoch in range(2000):
2 optimizer.zero_grad()
----> 3 out = model(data)
4 loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
5 loss.backward()
~/anaconda3/envs/gcn/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1049 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1050 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1051 return forward_call(*input, **kwargs)
1052 # Do not call functions when jit is used
1053 full_backward_hooks, non_full_backward_hooks = [], []
<ipython-input-84-0bf0aa6f166c> in forward(self, data)
8 def forward(self, data):
9 x, edge_index = data.x, data.edge_index
---> 10 x = self.conv1(x, edge_index)
11 x = F.relu(x)
12 x = F.dropout(x, training=self.training)
~/anaconda3/envs/gcn/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1049 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1050 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1051 return forward_call(*input, **kwargs)
1052 # Do not call functions when jit is used
1053 full_backward_hooks, non_full_backward_hooks = [], []
~/anaconda3/envs/gcn/lib/python3.7/site-packages/torch_geometric/nn/conv/hypergraph_conv.py in forward(self, x, hyperedge_index, hyperedge_weight, hyperedge_attr)
139
140 D = scatter_add(hyperedge_weight[hyperedge_index[1]],
--> 141 hyperedge_index[0], dim=0, dim_size=num_nodes)
142 D = 1.0 / D
143 D[D == float("inf")] = 0
~/anaconda3/envs/gcn/lib/python3.7/site-packages/torch_scatter/scatter.py in scatter_add(src, index, dim, out, dim_size)
27 out: Optional[torch.Tensor] = None,
28 dim_size: Optional[int] = None) -> torch.Tensor:
---> 29 return scatter_sum(src, index, dim, out, dim_size)
30
31
~/anaconda3/envs/gcn/lib/python3.7/site-packages/torch_scatter/scatter.py in scatter_sum(src, index, dim, out, dim_size)
19 size[dim] = int(index.max()) + 1
20 out = torch.zeros(size, dtype=src.dtype, device=src.device)
---> 21 return out.scatter_add_(dim, index, src)
22 else:
23 return out.scatter_add_(dim, index, src)
RuntimeError: index 2268264 is out of bounds for dimension 0 with size 2268264
I am clueless about how to fix this.Note that 2268264 is the number of nodes in the graph.
I mimicked the dataset construction from https://pytorch-geometric.readthedocs.io/en/latest/notes/introduction.html so I am not sure what mistake I did here.
I am trying to convert my Tensorflow graph to use a custom tensorflow estimator, but I am getting stuck defining the function for input_fn ; I am currently getting an error.
This is the function I use to generate my input data and labels
data_index = 0
epoch_index = 0
recEpoch_indexA = 0 #Used to help keep store of the total number of epoches with the models
def generate_batch(batch_size, inputCount):
global data_index, epoch_index
batch = np.ndarray(shape=(batch_size, inputCount), dtype=np.int32)
labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
n=0
while n < batch_size:
if len( set(my_data[data_index, 1]) ) >= inputCount:
labels[n,0] = my_data[data_index, 0]
batch[n] = random.sample( set(my_data[data_index, 1]), inputCount)
n = n+1
data_index = (data_index + 1) % len(my_data) #may have to do something like len my_data[:]
if data_index == 0:
epoch_index = epoch_index + 1
print('Completed %d Epochs' % epoch_index)
else:
data_index = (data_index + 1) % len(my_data)
if data_index == 0:
epoch_index = epoch_index + 1
print('Completed %d Epochs' % epoch_index)
return batch, labels
This is where I define my Estimator and attempt to do training
#Define the estimator
word2vecEstimator = tf.estimator.Estimator(
model_fn=my_model,
params={
'batch_size': 1024,
'embedding_size': 50,
'num_inputs': 5,
'num_sampled':128
})
batch_size = 16
num_inputs = 3
#Train with Estimator
word2vecEstimator.train(
input_fn=generate_batch(batch_size, num_inputs),
steps=10)
This is the error message that I get
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/usr/lib/python3.6/inspect.py in getfullargspec(func)
1118 skip_bound_arg=False,
-> 1119 sigcls=Signature)
1120 except Exception as ex:
/usr/lib/python3.6/inspect.py in _signature_from_callable(obj, follow_wrapper_chains, skip_bound_arg, sigcls)
2185 if not callable(obj):
-> 2186 raise TypeError('{!r} is not a callable object'.format(obj))
2187
TypeError: (array([[1851833, 670357, 343012],
[ 993526, 431296, 935528],
[ 938067, 1155719, 2277388],
[ 534965, 1125669, 1665716],
[1412657, 2152211, 1176177],
[ 268114, 2097642, 2707258],
[1280762, 1516464, 453615],
[2545980, 2302607, 2421182],
[1706260, 2735027, 292652],
[1802025, 2949676, 653015],
[ 854228, 2626773, 225486],
[1747135, 1608478, 2503487],
[1326661, 272883, 2089444],
[3082922, 1359481, 621031],
[2636832, 1842777, 1979638],
[2512269, 1617986, 389356]], dtype=int32), array([[1175598],
[2528125],
[1870906],
[ 643521],
[2349752],
[ 754986],
[2277570],
[2121120],
[2384306],
[1881398],
[3046987],
[2505729],
[2908573],
[2438025],
[ 441422],
[2355625]], dtype=int32)) is not a callable object
The above exception was the direct cause of the following exception:
TypeError Traceback (most recent call last)
<ipython-input-15-7acc939af001> in <module>()
5 word2vecEstimator.train(
6 input_fn=generate_batch(batch_size, num_inputs),
----> 7 steps=10)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in train(self, input_fn, hooks, steps, max_steps, saving_listeners)
352
353 saving_listeners = _check_listeners_type(saving_listeners)
--> 354 loss = self._train_model(input_fn, hooks, saving_listeners)
355 logging.info('Loss for final step: %s.', loss)
356 return self
/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in _train_model(self, input_fn, hooks, saving_listeners)
1205 return self._train_model_distributed(input_fn, hooks, saving_listeners)
1206 else:
-> 1207 return self._train_model_default(input_fn, hooks, saving_listeners)
1208
1209 def _train_model_default(self, input_fn, hooks, saving_listeners):
/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in _train_model_default(self, input_fn, hooks, saving_listeners)
1232 features, labels, input_hooks = (
1233 self._get_features_and_labels_from_input_fn(
-> 1234 input_fn, model_fn_lib.ModeKeys.TRAIN))
1235 worker_hooks.extend(input_hooks)
1236 estimator_spec = self._call_model_fn(
/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in _get_features_and_labels_from_input_fn(self, input_fn, mode)
1073 """Extracts the `features` and labels from return values of `input_fn`."""
1074 return estimator_util.parse_input_fn_result(
-> 1075 self._call_input_fn(input_fn, mode))
1076
1077 def _extract_batch_length(self, preds_evaluated):
/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in _call_input_fn(self, input_fn, mode)
1151 ValueError: if `input_fn` takes invalid arguments.
1152 """
-> 1153 input_fn_args = function_utils.fn_args(input_fn)
1154 kwargs = {}
1155 if 'mode' in input_fn_args:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/util/function_utils.py in fn_args(fn)
54 if _is_callable_object(fn):
55 fn = fn.__call__
---> 56 args = tf_inspect.getfullargspec(fn).args
57 if _is_bounded_method(fn):
58 args.remove('self')
/usr/local/lib/python3.6/dist-packages/tensorflow/python/util/tf_inspect.py in getfullargspec(obj)
214 return next((d.decorator_argspec
215 for d in decorators
--> 216 if d.decorator_argspec is not None), _getfullargspec(target))
217
218
/usr/lib/python3.6/inspect.py in getfullargspec(func)
1123 # else. So to be fully backwards compatible, we catch all
1124 # possible exceptions here, and reraise a TypeError.
-> 1125 raise TypeError('unsupported callable') from ex
1126
1127 args = []
TypeError: unsupported callable
Here is a link to the Google Colab notebook for people to run on their own. For anyone looking to execute this, this will download a data file that is ~500 mbs.
https://colab.research.google.com/drive/1LjIz04xhRi5Fsw_Q3IzoG_5KkkXI3WFE
And here is the full code, from the notebook.
import math
import numpy as np
import random
import zipfile
import shutil
from collections import namedtuple
import os
import pprint
import tensorflow as tf
import pandas as pd
import pickle
from numpy import genfromtxt
!pip install -U -q PyDrive
from google.colab import files
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
vocabulary_size = 3096637 #updated 10-25-18 3096636
import gc
dl_id = '19yha9Scxq4zOdfPcw5s6L2lkYQWenApC' #updated 10-22-18
myDownload = drive.CreateFile({'id': dl_id})
myDownload.GetContentFile('Data.npy')
my_data = np.load('Data.npy')
#os.remove('Data.npy')
np.random.shuffle(my_data)
print(my_data[0:15])
data_index = 0
epoch_index = 0
recEpoch_indexA = 0 #Used to help keep store of the total number of epoches with the models
def generate_batch(batch_size, inputCount):
global data_index, epoch_index
batch = np.ndarray(shape=(batch_size, inputCount), dtype=np.int32)
labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
n=0
while n < batch_size:
if len( set(my_data[data_index, 1]) ) >= inputCount:
labels[n,0] = my_data[data_index, 0]
batch[n] = random.sample( set(my_data[data_index, 1]), inputCount)
n = n+1
data_index = (data_index + 1) % len(my_data) #may have to do something like len my_data[:]
if data_index == 0:
epoch_index = epoch_index + 1
print('Completed %d Epochs' % epoch_index)
else:
data_index = (data_index + 1) % len(my_data)
if data_index == 0:
epoch_index = epoch_index + 1
print('Completed %d Epochs' % epoch_index)
return batch, labels
def my_model( features, labels, mode, params):
# train_dataset = tf.placeholder(tf.int32, shape=[batch_size, num_inputs ])
# train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])
train_dataset = features
train_labels = labels
batch_sizeE=params["batch_size"]
embedding_sizeE=params["embedding_size"]
num_inputsE=params["num_inputs"]
num_sampledE=params["num_sampled"]
epochCount = tf.get_variable( 'epochCount', initializer= 0) #to store epoch count to total # of epochs are known
update_epoch = tf.assign(epochCount, epochCount + 1)
embeddings = tf.get_variable( 'embeddings', dtype=tf.float32,
initializer= tf.random_uniform([vocabulary_size, embedding_sizeE], -1.0, 1.0, dtype=tf.float32) )
softmax_weights = tf.get_variable( 'softmax_weights', dtype=tf.float32,
initializer= tf.truncated_normal([vocabulary_size, embedding_sizeE],
stddev=1.0 / math.sqrt(embedding_sizeE), dtype=tf.float32 ) )
softmax_biases = tf.get_variable('softmax_biases', dtype=tf.float32,
initializer= tf.zeros([vocabulary_size], dtype=tf.float32), trainable=False )
embed = tf.nn.embedding_lookup(embeddings, train_dataset) #train data set is
embed_reshaped = tf.reshape( embed, [batch_sizeE*num_inputs, embedding_sizeE] )
segments= np.arange(batch_size).repeat(num_inputs)
averaged_embeds = tf.segment_mean(embed_reshaped, segments, name=None)
loss = tf.reduce_mean(
tf.nn.sampled_softmax_loss(weights=softmax_weights, biases=softmax_biases, inputs=averaged_embeds,
sampled_values=tf.nn.uniform_candidate_sampler(true_classes=tf.cast(train_labels, tf.int64), num_sampled=num_sampled, num_true=1, unique=True, range_max=vocabulary_size, seed=None),
labels=train_labels, num_sampled=num_sampled, num_classes=vocabulary_size))
optimizer = tf.train.AdagradOptimizer(1.0).minimize(loss)
saver = tf.train.Saver()
#Define the estimator
word2vecEstimator = tf.estimator.Estimator(
model_fn=my_model,
params={
'batch_size': 1024,
'embedding_size': 50,
'num_inputs': 5,
'num_sampled':128
})
batch_size = 16
num_inputs = 3
#Train with Estimator
word2vecEstimator.train(
input_fn=generate_batch(batch_size, num_inputs),
steps=10)
There's no way of correcting the function, cuz it can never be implemented using Tensorflow. The input_fn() function must return Tensors, not numpy arrays, cuz the input_fn() is a function constructing the graph, and it maybe is just called once when building the graph. In this context, the numpy array is just a constant value. It may seem to be weird, But it's the truth. You need to understand the mechanism of Tensorflow: the STATIC COMPUTE GRAPH!
Answer here
Tensorflow error : unsupported callable
train method accepts the input function, so it should be input_fn, not input_fn().