All I have a input layer and I am trying to do zero padding to make it a specific dimension of TensorShape([1, 1, 104, 24])
import tensorflow as tf
import dumpy as np
input_shape = (1, 1, 1, 24)
x = np.arange(np.prod(input_shape)).reshape(input_shape) # (1, 1, 1, 24)
y = tf.keras.layers.ZeroPadding2D(padding=(0, 51))(x)
y.shape # TensorShape([1, 1, 103, 24])
# how do I make the y.shape --> [1, 1, 104, 24]??
How do I change the param of the y so that I can have a shape of [1,1,104, 24]?
You are using:
padding = (0, 51)
This means: (symmetric_height_pad, symmetric_width_pad).
I.e. you are adding 51 zeros to left and right to you number, hence you get 51 + 1 + 51 = 103 items. To get 104, you can add for example 51 to left and 52 to right using:
padding=((0, 0), (51, 52))
Here the numbers mean: ((top_pad, bottom_pad), (left_pad, right_pad))
Related
I am using matplotlib.pyplot to make a histogram. Due to the distribution of the data, I want manually set up the bins. The details are as follows:
Any value = 0 in one bin;
Any value > 60 in the last bin;
Any value > 0 and <= 60 are in between the bins described above and the bin size is 5.
Could you please give me some help? Thank you.
I'm not sure what you mean by "the bin size is 5". You can either plot a histogramm by specifying the bins with a sequence:
import matplotlib.pyplot as plt
data = [0, 0, 1, 2, 3, 4, 5, 6, 35, 60, 61, 82, -5] # your data here
plt.hist(data, bins=[0, 0.5, 60, max(data)])
plt.show()
But the bin size will match the corresponding interval, meaning -in this example- that the "0-case" will be barely visible:
(Note that 60 is moved to the last bin when specifying bins as a sequence, changing the sequence to [0, 0.5, 59.5, max(data)] would fix that)
What you (probably) need is first to categorize your data and then plot a bar chart of the categories:
import matplotlib.pyplot as plt
import pandas as pd
data = [0, 0, 1, 2, 3, 4, 5, 6, 35, 60, 61, 82, -5] # your data here
df = pd.DataFrame()
df['data'] = data
def find_cat(x):
if x == 0:
return "0"
elif x > 60:
return "> 60"
elif x > 0:
return "> 0 and <= 60"
df['category'] = df['data'].apply(find_cat)
df.groupby('category', as_index=False).count().plot.bar(x='category', y='data', rot=0, width=0.8)
plt.show()
Output:
building off Tranbi's answer, you could specify the bin edges as detailed in the link they shared.
import matplotlib.pyplot as plt
import pandas as pd
data = [0, 0, 1, 2, 3, 4, 5, 6, 35, 60, 61, 82, -6] # your data here
df = pd.DataFrame()
df['data'] = data
bin_edges = [-5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65]
bin_edges_offset = [x+0.000001 for x in bin_edges]
plt.figure()
plt.hist(df['data'], bins=bin_edges_offset)
plt.show()
histogram
IIUC you want a classic histogram for value between 0 (not included) and 60 (included) and add two bins for 0 and >60 on the side.
In that case I would recommend plotting the 3 regions separately:
import matplotlib.pyplot as plt
data = [0, 0, 1, 2, 3, 4, 5, 6, 35, 60, 61, 82, -3] # your data here
fig, axes = plt.subplots(1,3, sharey=True, width_ratios=[1, 12, 1])
fig.subplots_adjust(wspace=0)
# counting 0 values and drawing a bar between -5 and 0
axes[0].bar(-5, data.count(0), width=5, align='edge')
axes[0].xaxis.set_visible(False)
axes[0].spines['right'].set_visible(False)
axes[0].set_xlim((-5, 0))
# histogram between (0, 60]
axes[1].hist(data, bins=12, range=(0.0001, 60.0001))
axes[1].yaxis.set_visible(False)
axes[1].spines['left'].set_visible(False)
axes[1].spines['right'].set_visible(False)
axes[1].set_xlim((0, 60))
# counting values > 60 and drawing a bar between 60 and 65
axes[2].bar(60, len([x for x in data if x > 60]), width=5, align='edge')
axes[2].xaxis.set_visible(False)
axes[2].yaxis.set_visible(False)
axes[2].spines['left'].set_visible(False)
axes[2].set_xlim((60, 65))
plt.show()
Output:
Edit: If you wanna plot probability density, I would edit the data and simply use hist:
import matplotlib.pyplot as plt
data = [0, 0, 1, 2, 3, 4, 5, 6, 35, 60, 61, 82, -3] # your data here
data2 = []
for el in data:
if el < 0:
pass
elif el > 60:
data2.append(61)
else:
data2.append(el)
plt.hist(data2, bins=14, density=True, range=(-4.99,65.01))
plt.show()
I want to make a projection to the tensor of shape [197, 1, 768] to [197,1,128] in pytorch using nn.Conv()
You could achieve this using a wide flat kernel and/or combined with a specific stride. If you stick with a dilation of 1, then the input/output spatial dimension relation is given by:
out = [(2p + x - k)/s + 1]
Where p is the padding, k is the kernel size and s is the stride. [] detonates the whole part of the quantity.
Applied here you have:
128 = [(2p + 768 - k)/s + 1]
So you would get:
p = 2*p + 768 - (128-1)*s # one off
If you impose p = 0, and s = 6 you find k = 6
>>> project = nn.Conv2d(197, 197, kernel_size=(1, 6), stride=6)
>>> project(torch.rand(1, 197, 1, 768)).shape
torch.Size([1, 197, 1, 128])
Alternatively, a more straightforward - but different - approach is to learn a mapping using a fully connected layer:
>>> project = nn.Linear(768, 128)
>>> project(torch.rand(1, 197, 1, 768)).shape
torch.Size([1, 197, 1, 128])
You could use a kernel size and stride of 6, as that’s the factor between the input and output temporal size:
x = torch.randn(197, 1, 768)
conv = nn.Conv1d(in_channels=1, out_channels=1, kernel_size=6, stride=6)
out = conv(x)
print(out.shape)
> torch.Size([197, 1, 128])
Solution Source
These codes produce a chart
import numpy as np
import matplotlib.pyplot as plt
N = 5
menMeans = (20, 35, 30, 35, 27)
womenMeans = (25, 32, 34, 20, 25)
menStd = (2, 3, 4, 1, 2)
womenStd = (3, 5, 2, 3, 3)
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars: can also be len(x) sequence
p1 = plt.bar(ind, menMeans, width, yerr=menStd)
p2 = plt.bar(ind, womenMeans, width,
bottom=menMeans, yerr=womenStd)
plt.ylabel('Scores')
plt.title('Scores by group and gender')
plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('Men', 'Women'))
Jupyter notebook automatically print the chart, even I didn't call plt.show(). I don't want to show the chart in the same cell with the code but the next cell by running a really short code such as plt.show(). In order to keep the cell as concise as possible.
Just enclose all your plot-related statements inside a function called plot_and_show(). Then you can call the function when you are ready.
import matplotlib.pyplot as plt
import numpy as np
N = 5
menMeans = (20, 35, 30, 35, 27)
womenMeans = (25, 32, 34, 20, 25)
menStd = (2, 3, 4, 1, 2)
womenStd = (3, 5, 2, 3, 3)
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars: can also be len(x) sequence
def plot_and_show():
p1 = plt.bar(ind, menMeans, width, yerr=menStd)
p2 = plt.bar(ind, womenMeans, width,
bottom=menMeans, yerr=womenStd)
plt.ylabel('Scores')
plt.title('Scores by group and gender')
plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('Men', 'Women'))
plot_and_show()
Assume I have a Tensor in TensorFlow of shape [600, 11]. All the elements of the last (11th) column are zero. I want to iterate over the values of the Tensor like that: For each row, I check whether the maximum of the first 10 elements of the row is greater than a value X. If True, then keep the row unchanged, if False, then set the first 10 elements of the row to be equal to zero and make the 11th element equal to 1. How can I do that? The structure of my Tensor is shown below:
import tensorflow as tf
a = tf.zeros([600, 1], dtype=tf.float32)
b = tf.random.uniform([600,10], minval=0, maxval=1, dtype=tf.float32)
c = tf.concat([b, a], axis=1)
You cannot iterate through tensors, nor set the value of individual elements. Tensors are immutable, so you always have to build a new tensor from the previous one instead. This is how you can do something like what you describe:
import tensorflow as tf
def modify_matrix(matrix, X):
all_but_last_column = matrix[:, :-1]
max_per_row = tf.reduce_max(all_but_last_column, axis=1)
replace = tf.concat([tf.zeros_like(all_but_last_column),
tf.ones_like(matrix[:, -1])[:, tf.newaxis]], axis=1)
mask = max_per_row > X
return tf.where(mask, matrix, replace)
nums = [list(range(i * 10, (i + 1) * 10)) + [0] for i in range(1, 5)]
print(*nums, sep='\n')
# [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0]
# [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0]
# [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0]
# [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0]
matrix = tf.constant(nums)
X = tf.constant(36, dtype=matrix.dtype)
result = modify_matrix(matrix, X)
print(sess.run(result))
# [[ 0 0 0 0 0 0 0 0 0 0 1]
# [ 0 0 0 0 0 0 0 0 0 0 1]
# [30 31 32 33 34 35 36 37 38 39 0]
# [40 41 42 43 44 45 46 47 48 49 0]]
I also found another solution that it worked for me:
import tensorflow as tf
zeroes = tf.zeros([600, 1], dtype=tf.float32)
ones = tf.ones([600, 1], dtype=tf.float32)
b = tf.random.uniform([600,10], minval=0, maxval=1, dtype=tf.float32)
threshold = tf.constant(0.6, dtype=tf.float32)
check = tf.reduce_max(tf.cast(b > threshold, dtype=tf.float32), axis=1)
last_col = tf.where(check>0, zeroes, ones)
new_b = tf.where(check>0, b, tf.zeros([600, 10], dtype=tf.float32))
new_matrix = tf.concat([new_b, last_col], axis=1)
Here is the code of model including convolutional layers and training function using tensorflow. After coding all the layers of model, flatten layer is not giving an expected output which contains tf.reshape(). Please help me .
def model(self, inp):
# Layer 3
layer3_conv1 = tf.nn.conv2d(layer2_max_pool1, self.__W[3], strides=[1, 1, 1, 1], padding=self.padding)
layer3_relu1 = tf.nn.relu(tf.nn.bias_add(layer3_conv1, self.__b[3]))
layer3_max_pool1 = tf.nn.max_pool(layer3_relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding=self.padding)
w4 = (layer3_max_pool1.get_shape()[1:]).as_list()
print("layer3maxpool shape is ",layer3_max_pool1.shape)
print("w4 shape is ",w4)
# Flatten
print ("x is :",np.prod(w4))
flatten = tf.reshape(layer3_max_pool1, [ -1,np.prod(w4)])
print(" Flatten shape is",flatten.shape)
# Fully Connected Network
fc1 = tf.nn.relu(tf.matmul(flatten, self.__W[4]) + self.__b[4])
print(fc1.shape)
out = tf.nn.relu(tf.matmul(fc1, self.__W[5]) + self.__b[5])
# print(out.get_shape().as_list())
return out
Output is :
layer3maxpool shape is (?, 45, 58, 256)
> w4 shape is [45, 58, 256]
> x is : 668160
Flatten shape is (?, 668160)
> (?, 1024)