If my model is trained using sigmoid at the final layer and binary_crossentropy, can I shtill out put probability of classes rather than 0/1? - label

I have trained a CNN model with dense layer at the end using a sigmoid function:
model.add(layers.Dense(1, activation='sigmoid'))
I have also compiled using binary cross entropy:
model.compile(loss='binary_crossentropy',
optimizer = 'Adam',
metrics=[tf.keras.metrics.Precision(),tf.keras.metrics.Recall(),'accuracy'])
The f1 score of the binary images classification comes low and my model predicts one class over the other. So I decided to add a threshold based on the output probability of my sigmoid function at the final layer:
c = load_img('/home/kenan/Desktop/COV19D/validation/covid/ct_scan_19/120.jpg',
color_mode='grayscale',
target_size = (512,512))
c=img_to_array(c)
c= np.expand_dims(c, axis=0)
pred = model.predict_proba(c)
pred
y_classes = ((model.predict(c)> 0.99)+0).ravel()
y_classes
I want to use 'pred' in my code as a probability of the class but it is always either 0 or 1 as shown below:
Out[113]: array([[1.]], dtype=float32)
why doesn't it give the probability of predicting the class between [0,1] instead of 1? is there a way to get the class probability in my case rather than 0 or 1?

No you cant. Sigmoid activation in the final layer will output ONE value in the range of 0 to 1. If you want to obtain class probabilities of the different labels, you'll have to change the final layer activation to softmax.

Related

How to output XGBoost output in log odds form in Python

I have a simple XGBClassifier
model = XGBClassifier()
which I use to fit a model (X are the predictive features, Y is the binary target):
model.fit(X, Y)
If I want to calculate the probabilities from the XGBClassifier model that I have just trained, then I use this code:
y_pred_proba = []
for i in range(len(X)):
y_pred_proba.append(0)
y_pred_proba[i] = model.predict_proba(X.iloc[[i]]).ravel()[1]
But how do I get the log(odds)?
If I applied the following formula:
ln(odds) = ln(probability / (1-probability))
I'd get the odds ratio. I guess you cannot convert the probabilities to odds as simple as that. I guess you need a sigmoid function, right?
I understand that the default XGBClassifier objective function is a logistic regression. Is there a command to output the log(odds) of the XGBClassifier?
If I had fit a logistic regression like this:
import sklearn
model_adult = sklearn.linear_model.LogisticRegression(max_iter=10000)
model_adult.fit(X, Y)
Then I could have generated the log(odds) output through this code:
print(model_adult.predict_log_proba(X))
Is there anything similar with XGBClassifier?

What is the name of this image similarity/ distance based metric?

I used the following code to calculate the similarity between images 1 and 2 (i1 and i2). 1=exactly similar while 0=very different. I'd like to know what method this algorithm is using (i.e. Euclidian distance or..?) Thank you.
import math
i1=all_images_saved[0][1]
i2=all_images_saved[0][2]
i1_norm = i1/np.sqrt(np.sum(i1**2))
i2_norm = i2/np.sqrt(np.sum(i2**2))
np.sum(i1_norm*i2_norm)
Looks like cosine similarity. You can check it gives the same results as:
from scipy import spatial
cosine_distance = spatial.distance.cosine(i1.flatten(), i2.flatten())
cosine_similarity = 1 - cosine_distance
I don't believe it's a distance, otherwise 0 would mean identical. This looks like the dot product of 2 normalized vectors in which case I would say about the original vectors that they are (with the range of values from -1 to 1 being in between the thresholds describe below):
1 = co-directional
0 = orthogonal
-1 = opposite direction
And given the geometric definition of the dot product, if you have the dot product and the magnitude of your vectors you can derive the angle between the 2:
a . b = ||a|| ||b|| cos θ
Or have I completely missed something here?

Python OLS with categorical label

I have a dataset where I am trying to predict the type of car based off of a number of features. I would like to an OLS regression to see
import statsmodels.api as sm
X = features
# where 0 = sedan, 1 = minivan , etc
y = [0,0,1,0,2,....]
X2 = sm.add_constant(np.array(X))
est = sm.OLS(np.array(y), X2)
est2 = est.fit()
^ I don't feel like doing this is correct because I am not specifying that it is categorical, I feel like the functional form should change. Was wondering if anyone had any insight on this.
Ordinary least squares regression assumes a numerical dependent variable, you cannot use it to predict categorical outcomes.
To predict categorical outcomes with a regression model, you want to use multinomial logistic regression, for example using sklearn.

integration of multidimensional data (matlab)

I have a (somewhat complicated expression) in three dimensions, x,y,z. I'm interested in the cumulative integral over one of them. My best solution thus far is to create a 3D grid, evaluate the expression at every point, then integrate over the third dimension with cumtrapz. This is just a scaled down example of what I'm trying to achieve:
%integration
xvec = linspace(-pi,pi,40);
yvec = linspace(-pi,pi,40);
zvec = 1:160;
[x,y,z] = meshgrid(xvec,yvec,zvec);
f = #(x,y,z) sin(x).*cos(y).*exp(z/80).*cos((x-z/20));
output = cumtrapz(f(x,y,z),3);
%(plotting)
for j = 1:length(output(1,1,:));
surf(output(:,:,j));
zlim([-120,120]);
shading interp
pause(.05);
drawnow;
end
Given the sizes of vectors (x,y~100, z~5000), is this a computationally sensible way to do this?
if this is the function form you want to integrate over,#(x,y,z) sin(x).*cos(y).*exp(z/80).*cos((x-z/20)), x,y,z can be separately integrated and the integral can be analytically solved using complex number by replacing sin(x)=(exp(ix)-exp(ix))/2i, and cos(x)=(exp(ix)+exp(ix))/2, which will greatly reduce the time cost of your calculation

implement Gaussian distribution with singular sigma

I am implementing the Gaussian distribution model on some data, if the sigma(covariance matrix) is singular, then it's not invertible, and will result in the failure in calculating the probability. I think add an Identity matrix to the sigma will make the sigma invertible, but that will make the model not fits the data.
Is there a way to make the sigma matrix invertible and keep the model fitting data?
Have a set of data: (x1, x2)_1 , (x1, x2)_2 , ... , (x1, x2)_i . where x1 and x2 are continues real numbers and some (x1, x2) can appear serval times, And I assumpt that those data follow Guassian distribution, and then can calculate the mean vector as (mean(x1), mean(x2)), and then calculate the covariance matrix as usual. And in some case the covariance matrix may be singular, I think add some random small shifts to it can make it nonsingular, but I don't know how to do it correctly so that the model can still fit data well.
You only need to model one dimension of the data with a 1D gaussian distribution in this case.
If you have two-dimensional data {(x1,x2)_i} whose covariance matrix is singular, this means that the data lies along a straight line. The {x2} data is a deterministic function of the {x1} data, so you only need to model the {x1} data randomly. The {x2} data follows immediately from {x1} and is no longer random once you know {x1}.
Here is my reasoning:
The covariance matrix would look something like this, since all covariance matrices are symmetric:
| a b |
| b c |
Where a = var(x1), c = var(x2), b = cov(x1,x2).
Now if this matrix is singular, the second column vector would have to be a scalar multiple of the first (since they are linearly dependent). Let's say the constant is k. Then:
b = k*c
a = k*b = k*k*c
So the covariance matrix really looks like:
| k*k*c k*c |
| k*c c |
Here there is only one parameter c = var(x2) which determines the distribution (since k can be anything), so the data in inherently one-dimension. Modelling it with one variable x1 is enough. Another way of seeing this is by checking that the Pearson Correlation Coefficient for this distribution is b/(sqrt(a)*sqrt(c)) = 1.

Resources