Grad-cam not working properly in keras with inceptionv3 - python

I am using visualise cam from keras-vis for creating guided-gradcam images.
The grad-cam is working perfectly well with vgg16. but when i used the same code for inceptionv3 it is not working properly.
from keras.applications.inception_v3 import InceptionV3
from vis.utils import utils
from keras.preprocessing import image
import numpy as np
from keras import activations
from matplotlib import pyplot as plt
%matplotlib inline
from vis.visualization import visualize_cam,overlay
#build the inceptionv3 model with imagenet weights
model = InceptionV3(weights='imagenet',include_top=True)
# Utility to search for layer index by name
layer_idx = utils.find_layer_idx(model,'predictions')
#swap with softmax with linear classifier for the reasons mentioned above
model.layers[layer_idx].activation = activations.linear
model = utils.apply_modifications(model)
from vis.utils import utils
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize']=(18,6)
img1 = utils.load_img('images/ouzel1.jpg',target_size=(299,299))
img2 = utils.load_img('images/ouzel2.jpg',target_size=(299,299))
f, ax = plt.subplots(1,2)
ax[0].imshow(img1)
ax[1].imshow(img2)
plt.show()
from vis.visualization import visualize_cam
for modifier in [None, 'guided', 'relu']:
plt.figure()
f, ax = plt.subplots(1, 2)
plt.suptitle("vanilla" if modifier is None else modifier)
for i, img in enumerate([img1, img2]):
# 20 is the imagenet index corresponding to `ouzel`
heatmap = visualize_cam(model, layer_idx, filter_indices=20,
seed_input=img, backprop_modifier=modifier,
#penultimate_layer_idx = 299 # corresponding to "conv2d_94"
)
# Lets overlay the heatmap onto original image.
ax[i].imshow(overlay(img, heatmap))
by commenting out the line #penultimate_layer also I am getting the same output which is not correct. can someone tell me what is the problem? The guided-grad cam result is given , followed by the original image is given.
The problem is the heatmap must be on the bird (ouzel).

I hit the very same problem, but then I discovered that InceptionV3 mis-classifies these images. Check:
>>> model.predict(np.stack([img1, img2], 0)).argmax(axis=1)
array([110, 725])
While with VGG it's:
>>> model.predict(np.stack([img1, img2], 0)).argmax(axis=1)
array([20, 20])

Related

How get the predicted label from a detectron2 visualizer function

I am working detectron2 object detection model, which produced a good output result. I can also see the output predicted result with labels with the help of detectron2.utils.visualizer Visualizer functions like the following:
predicted result image
The code I used the display the resulting image is:
`import cv2
import matplotlib.pyplot as plt
predictor = DefaultPredictor(cfg)
im = cv2.imread("./test_images/img9.jfif")
print(im.shape)
plt.figure(figsize=(15,7.5))
plt.imshow(im[..., ::-1])
outputs = predictor(im[..., ::-1])`
from detectron2.utils.visualizer import Visualizer
from detectron2.utils.visualizer import ColorMode
v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]), scale=1.2)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
plt.figure(figsize=(20,10))
plt.imshow(out.get_image()[..., ::-1][..., ::-1])
But I want to print the predicted labels and save them in the direction from top left side. Ex. Dhaka Metro- Ga 1- 57 How can I do this?

Is there any way to open the model performance graphs of TensorBoard, in Python or R?

I need to open this TensorBoard graph in Python or R.
You could use summary_iterator to read the event file generated by Tensorflow and make_ndarray to extract the tensor values from it.
Setup
import tensorflow as tf
import numpy as np
TAG_NAME = "classification_loss"
writer_train = tf.summary.create_file_writer("train")
for epoch in range(200):
data = np.math.exp(-(epoch/30)) + 0.1*np.random.random()
with writer_train.as_default():
tf.summary.scalar(name=TAG_NAME, data=data, step=epoch)
# output folder: train/events.out.tfevents.1618103384.eafddbceac44.283.2075165.v2
Read event file
import tensorflow as tf
import matplotlib.pyplot as plt
TAG_NAME = "classification_loss"
tf_event_file = "train/events.out.tfevents.1618103384.eafddbceac44.283.2075165.v2"
value_list = []
for e in tf.compat.v1.train.summary_iterator(tf_event_file):
for v in e.summary.value:
if v.tag == TAG_NAME:
value = tf.make_ndarray(v.tensor)
value_list.append(value)
plt.plot(value_list)
plt.grid()
plt.show()
Actually, the best and easiest way is you can download the graph data in CSV or JSON format from Tensorboard. Once you have graph data you can import data and plot it.
import tensorflow as tf
import matplotlib.pyplot as plt
def get_scalar_run_tensorboard(tag, filepath):
values,steps = [],[]
for e in tf.compat.v1.train.summary_iterator(filepath):
if len(e.summary.value)>0: #Skip first empty element
if e.summary.value[0].tag==tag:
tensor = (e.summary.value[0].tensor)
value,step = (tf.io.decode_raw(tensor.tensor_content,tf.float32)[0].numpy(),e.step)
values.append(value)
steps.append(step)
return values,steps
e.g.
val,st = get_scalar_run_tensorboard("epoch_loss",
"./logs/your_log/your_run/train/your_file.v2")
import matplotlib.pyplot as plt
plt.plot(st,val)

Pytorch error: ValueError: pic should be 2/3 dimensional. Got 4 dimensions [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Trying to follow this tutorial here. Although when I select my content image and style image when I try to use the imshow() function I am getting this error:
ValueError: pic should be 2/3 dimensional. Got 4 dimensions.
Using google I have not been able to really find any remedy to this problem.
Here is my code:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from PIL import Image
import matplotlib.pyplot as plt
import torchvision.transforms as transforms
import torchvision.models as models
import copy
import numpy as np
# This detects if cuda is available for GPU training otherwise will use CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)
# Desired size of the output image
imsize = 512 if torch.cuda.is_available() else 256
print(imsize)
# Helper function
def image_loader(image_name, imsize):
# Scale the imported image and transform it into a torch tensor
loader = transforms.Compose([transforms.Resize(imsize), transforms.ToTensor()])
image = Image.open(image_name)
# Fake batch dimension required to fit network's input dimension
image = loader(image).unsqueeze(0)
return image.to(device, torch.float)
# Helper function to show the tensor as a PIL image
def imshow(tensor, title=None):
unloader = transforms.ToPILImage()
image = tensor.cpu().clone()
image = unloader(image)
plt.imshow(image)
if title is not None:
plt.title(title)
plt.pause(0.001) # Pause so that the plots are updated
# Loading of images
image_directory = './images/'
style_img = image_loader(image_directory + "pb.jpg", imsize)
content_img = image_loader(image_directory + "content.jpg", imsize)
assert style_img.size() == content_img.size(), "we need to import style and content images of the same size"
plt.figure()
imshow(style_img, title='style image')
Any suggestions would be really helpful.
Here is the style and content image for reference:
matplotlib.pyplot expects either 2D (grayscale, dimensions=(W,H)) or 3D (colored, dimensions = (W,H,color channel)) in the imshow-function.
You probably still have the batchsize as a first dimension in your tensor, because in your code you do:
# Fake batch dimension required to fit network's input dimension
image = loader(image).unsqueeze(0)
which adds this first dimensions. If so, try either to use:
plt.imshow(np.squeeze(image))
or
plt.imshow(image[0])

Numpy append sometimes works, sometimes doesn't

so I've been working on this facial identification project. It's for my science fair and I'm in the phase where I'm trying to get data graphs, plots, and visualizations. I've got it to work to some extent, but it's not consistent (in terms of execution).
The thing is, sometimes the code works, sometimes it'll give me an error.
For some context, the error is with Numpy append(). I have a variable I want to append data to but when it doesn't work the error is AttributeError: 'numpy.ndarray' object has no attribute 'append'
#Although the results aren't as expected, this can make for a good demo in ISEF
#The whole refresh after a face is detected is cool and can be used to show how different faces cluster
# Numerical computation requirements
import numpy as np
from numpy import linalg, load, expand_dims, asarray, savez_compressed, append
from numpy.linalg import norm
import pandas as pd
# Plotting requirements
import matplotlib
from matplotlib import pyplot as plt
import matplotlib.patheffects as PathEffects
from matplotlib.animation import FuncAnimation as ani
import seaborn as sb
# Clustering requirements
import sklearn
from sklearn.cluster import KMeans
from sklearn.manifold import TSNE
from sklearn.preprocessing import scale
# Miscellaneous requirements
import os
import cv2
from PIL import Image
from mtcnn.mtcnn import MTCNN
from keras.models import load_model
from scipy.spatial.distance import squareform, pdist
# Initialize RNG seed and required size for Facenet
seed = 12345678
size = (160,160)
# Required networks
facenet = load_model('facenet_keras.h5')
fd = MTCNN()
# Initialize Seaborn plots
sb.set_style('darkgrid')
sb.set_palette('muted')
sb.set_context('notebook', font_scale=1.5, rc={'lines.linewidth': 2.5})
# Matplotlib animation requirements?
plt.style.use('fivethirtyeight')
fig = plt.figure()
# Load embeddings
data = load('jerome only npz/jerome embeddings.npz')
Data_1 = data['arr_0']
Dataset = []
for array in Data_1:
Dataset.append(np.expand_dims(array, axis=0))
# Create cluster
cluster = KMeans(n_clusters=2, random_state=0).fit(Data_1)
y = cluster.labels_
z = pd.DataFrame(y.tolist())
faces = list()
def scatter(x,colors):
palette = np.array(sb.color_palette('hls', 26))
plot = plt.figure()
ax = plt.subplot(aspect='equal')
# sc = ax.scatter(x[:,0],x[:,1], lw =0, s=120, c=palette[colors.astype(np.int)])
sc = ax.scatter(x[:,0],x[:,1], lw =0, s=120)
labels = []
return plot , ax, sc, labels
def detembed():
cam = cv2.VideoCapture(0)
_,frame = cam.read()
info = fd.detect_faces(frame)
if info != []:
for i in info:
print("***************** FACE DETECTED *************************************************")
x,yc,w,h = i['box']
x,y = abs(x), abs(yc)
w,h = abs(w), abs(h)
xx, yy = x+w, yc+h
#cv2.rectangle(frame, (x,y), (xx,yy), (0,0,255),2)
face = frame[yc:yy, x:xx]
image = Image.fromarray(face)
image = image.resize(size)
arr = asarray(image)
arr = arr.astype('float32')
mean, std = arr.mean(), arr.std()
arr = (arr - mean) / std
samples = expand_dims(arr, axis=0)
faces.append(samples)
#cv2.imshow('Camera Feed', frame)
while True:
detembed()
embeddings = Dataset
if not faces:
continue
else:
for face in faces:
embeds = facenet.predict(face)
#switch these if conflicts arise
embeddings.append(embeds)
embeddings = asarray(embeddings)
embeddings = embeddings[:,0,:]
cluster = KMeans(n_clusters=2, random_state=0).fit(Data_1)
y = cluster.labels_
points = TSNE(random_state=seed).fit_transform(embeddings)
# here "y" dictates the color of the plots depending on the kmeans algorithm
scatter(points,y)
graph = ani(fig, scatter, interval=20)
fcount = len(embeddings)
plt.text(0,0,'{} points'.format(fcount))
plt.show()
# reset embeddings var to initial dataset
Dataset = np.delete(Dataset, fcount - 1,0)
embeddings = Dataset
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.release()
cv2.destroyAllWindows
Note that I am not a talented programmer; this code was botched from some example I found online. I had to pick up Python as I went along with this project. I do have a background in C, so I would say I get the basics of code logic.
Please help. I'm getting really desperate; the science fair is getting closer and I am a high schooler with no ML mentor. I live on an island (Guam) with no machine learning practitioners (not even in the university), so I turn to Stackoverflow.
There's no issue with NumPy's append(). Here(3rd statement) you're trying to append a value to Numpy array without using NumPy's np.append().
Dataset.append(np.expand_dims(array, axis=0))
embeddings = Dataset
embeddings.append(embeds)
Since Datasets contain Numpy array after running the first statement, embeddings will also be a NumPy array and hence the operation fails whenever the execution comes here.
A simple fix would be to use this:
np.append(embeddings, embeds)
Or this,
embeddings = list(Dataset)
Hope that helps.

Implementing FFT with Pytorch

I am trying to implement FFT by using the conv1d function provided in Pytorch.
Generating artifical signal
import numpy as np
import torch
from torch.autograd import Variable
from torch.nn.functional import conv1d
from scipy import fft, fftpack
import matplotlib.pyplot as plt
%matplotlib inline
# Creating filters
d = 4096 # size of windows
def create_filters(d):
x = np.arange(0, d, 1)
wsin = np.empty((d,1,d), dtype=np.float32)
wcos = np.empty((d,1,d), dtype=np.float32)
window_mask = 1.0-1.0*np.cos(x)
for ind in range(d):
wsin[ind,0,:] = np.sin(2*np.pi*((ind+1)/d)*x)
wcos[ind,0,:] = np.cos(2*np.pi*((ind+1)/d)*x)
return wsin,wcos
wsin, wcos = create_filters(d)
wsin_var = Variable(torch.from_numpy(wsin), requires_grad=False)
wcos_var = Variable(torch.from_numpy(wcos),requires_grad=False)
# Creating signal
t = np.linspace(0,1,4096)
x = np.sin(2*np.pi*100*t)+np.sin(2*np.pi*200*t)+np.random.normal(scale=5,size=(4096))
plt.plot(x)
FFT with Pytorch
signal_input = torch.from_numpy(x.reshape(1,-1),)[:,None,:4096]
signal_input = signal_input.float()
zx = conv1d(signal_input, wsin_var, stride=1).pow(2)+conv1d(signal_input, wcos_var, stride=1).pow(2)
FFT with Scipy
fig = plt.figure(figsize=(20,5))
plt.plot(np.abs(fft(x).reshape(-1))[:500])
My Question
As you can see the two outputs are quite similar in terms of the peaks characteristics. That means my implementation is not totally wrong.
However, there are also some subtleties, such as the scale of the spectrum, and the signal to noise ratio. I am unable to figure out what's missing here to get the exact same result.
You calculated the power rather than the amplitude.
You simply need to add the line zx = zx.pow(0.5) to take the square root to get the amplitude.
As of version 1,8, PyTorch has a native implementation torch.fft:
torch.fft.fft(x)

Categories