Methods for splitting a dataset efficiently - validation

I have a fairly large dataset of images. They have been taken by 'x' number of photographers and each image falls into one of 'y' themes. How would I go about making a train, valid, test split if I want no photographer overlap between the splits and as minimal theme overlap as possible(i.e. theme overlap between valid and train is okay but not with test)?
Some themes are not captured by some photographers. I've tried first splitting the set by photographers and then try to combine these with minimal theme overlap but there's a lot of trial and error and I was wondering if there's a better way.

Well, you can use train_test_split function inside scikit-learn library to split your dataset into train and test. like below
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size = 0.2, random_state=42)
where
X = Features and Y = Labels
Then you can use cross_validate function that randomly takes some part of the training data as validation data and train it on the algorithm passed,
like below
from sklearn.model_selection import cross_validate
cv_results = cross_validate(algorithm, x_train, y_train, cv=3)
This is how your test data and train data won't overlap

Related

Why does the ResNet from the timm.models accept images of different sizes, although it is trained on 224

I use the ResNet50. ResNet50 is trained for image size 224x224. Why don't they give an error when I submit tensors (images) of a different size?
import torch
from timm.models.resnet import resnet50
y_pred = model_resnet50(torch.rand(4, 3, 224, 224)) # OK
y_pred = model_resnet50(torch.rand(4, 3, 537, 537)) # Again OK. Why? The size is not the one that was trained on ResNet50
I assume that it runs in convolutions throughout the image. It creates a different number of properties for different images (after forward_features). The Global Average Pooling layer brings everything to a one-dimensional vector. Therefore, the image size only affects the number of properties in front of the Dense layer. Is it so?
What size images are better to train then?

Deriving optimal trajectories on a manifold in GEKKO

I've finally gotten back to working on my project and have found my next hurdle.
I have an enclosed manifold:
Also here's an example trajectory in the game im modelling
that I can have my system drive on like a normal car. I'm curious what the best way to incorporate this type of constraint would be in gekko. The manifold looks like a cube with rounded edges and corners. My current thought is to create a MLP (multii layer perceptron) to approximate the normal vector on the manifold at each point in on the surface. I tried using the GEKKO brain model to do this but it ended up being very slow so I moved to a keras model. I now have a keras model that is about 89% percent accurate connecting positions to normal vectors (which might be enough).
So my first thing is, how can I incorporate the keras model into my gekko equations? If I'm able to calculate the derivative of the neural network output at each point as well would it be possible to black box the model such that gekko puts in a position and then the black box function spits out a normal vector and this normal vectors derivative to ultimately calculate optimal trajectories?
If this is not possible, do you think I could easily model this manifold as a bspline? And what would be the way I should approach making the manifold surface a constraint for the system while it's in the driving state? My thoughts were I would take the system's current velocity vector and dot it with the normal vector of the manifold at the system's position to get how much along the manifold the velocity vector rotates. I already see some problems like for example large time steps missing curvature of the manifold and causing the system to drive off the surface of the manifold. I think the typical way of doing this math is to project the system's velocity into the "tanget space" of the manifold, derive the future state in the tanget space then map back to the manifold using a retraction. I'm still fairly new to this topic of topology and manifolds so correct me if I've made a mistake on the theory.
I don't have much code yet doing this as I'm stuck figuring out how to use the keras model in an equation. I do have a simpler problem available which is instead of driving on this complex manifold I just drive on a circle in R2. I've modelled this circle in R2 using a keras model as well. I plan to start with the simpler version if I'm able to use keras in equations before I jump into driving on the manifold in R3.
Are there any examples doing something similar to this that I could learn form?
Thank You! Excited to get back into this project.
This path planning optimization application may be better with a shooting approach where the model is a "black box" that the optimizer repeatedly calls the simulator. Some of the challenges are the changing equations when the vehicle is interacting with the ground versus in the air. If you do want to try to model both ground and air, an if3 statement would allow the switching or else use slack variables.
For the boundary constraint, maybe there is a simpler way to start modeling it such as simple inequality constraints that would form a box. You could add additional inequality constraints for the edges to model the curvature.
Below is a related application with a rocket launch that is applicable to the air dynamics. You would need to extend this to 3D.
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
# create GEKKO model
m = GEKKO()
# scale 0-1 time with tf
m.time = np.linspace(0,1,101)
# options
m.options.NODES = 6
m.options.SOLVER = 3
m.options.IMODE = 6
m.options.MAX_ITER = 500
m.options.MV_TYPE = 0
m.options.DIAGLEVEL = 0
# final time
tf = m.FV(value=1.0,lb=0.1,ub=100)
tf.STATUS = 1
# force
u = m.MV(value=0,lb=-1.1,ub=1.1)
u.STATUS = 1
u.DCOST = 1e-5
# variables
s = m.Var(value=0)
v = m.Var(value=0,lb=0,ub=1.7)
mass = m.Var(value=1,lb=0.2)
# differential equations scaled by tf
m.Equation(s.dt()==tf*v)
m.Equation(mass*v.dt()==tf*(u-0.2*v**2))
m.Equation(mass.dt()==tf*(-0.01*u**2))
# specify endpoint conditions
m.fix(s, pos=len(m.time)-1,val=10.0)
m.fix(v, pos=len(m.time)-1,val=0.0)
# minimize final time
m.Obj(tf)
# Optimize launch
m.solve()
print('Optimal Solution (final time): ' + str(tf.value[0]))
# scaled time
ts = m.time * tf.value[0]
# plot results
plt.figure(1)
plt.subplot(4,1,1)
plt.plot(ts,s.value,'r-',linewidth=2)
plt.ylabel('Position')
plt.legend(['s (Position)'])
plt.subplot(4,1,2)
plt.plot(ts,v.value,'b-',linewidth=2)
plt.ylabel('Velocity')
plt.legend(['v (Velocity)'])
plt.subplot(4,1,3)
plt.plot(ts,mass.value,'k-',linewidth=2)
plt.ylabel('Mass')
plt.legend(['m (Mass)'])
plt.subplot(4,1,4)
plt.plot(ts,u.value,'g-',linewidth=2)
plt.ylabel('Force')
plt.legend(['u (Force)'])
plt.xlabel('Time')
plt.show()
Here is one more application with the landing of a reusable rocket with source files. They developed a surrogate model of the rocket dynamics to apply the model in predictive control.
This is an example of a 3D rocket application but they didn't have the complication of ground interaction with changing dynamic equations.

How to use Inception Network for Regression

I'm trying to input an image and get a continuous number as an output.
I built a NN which takes an image with only a single node in the Hidden layer with a linear activation function. However, the model predicts the same number for the given input.
Hence I would like to use the Inception Network for this problem. Based on a recent paper by Google.
Link: https://arxiv.org/pdf/1904.06435.pdf
x = Dense(1, activation="linear")(x)
This is absolutely possible! The example from keras documentation on pre-trained models should help you with your endeavor. Make sure to adjust the output layer and the loss of your new model.
Edit: code example for your specific case
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense
from keras import backend as K
# create the base pre-trained model
base_model = InceptionV3(weights='imagenet', include_top=False)
# add a global spatial average pooling layer
x = base_model.output
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
# and a linear output layer
prediction = Dense(1, activation='linear')(x)
# this is the model we will train
model = Model(inputs=base_model.input, outputs=prediction)
# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
layer.trainable = False
# compile the model (should be done *after* setting layers to non trainable)
model.compile(optimizer='rmsprop', loss='mean_squared_error')
# train the model on the new data for a few epochs
model.fit_generator(...)
This is just training the new top layers, if you like to fine-tune the lower layers as well have a look at the example from the documentation.

Superpose images via shell

I have two figures, one is a data plot resulting from some calculations and made with matplotlib and the other is a world map figure taken from google maps. I would like to reduce the matplotlib figure to some percentage value and superpose it over the map picture at certain position and get a final "mixed" picture. I know it can be done with graphical problems and so, but I would like to do it automatically on the shell for thousands of different cases, I wonder if you could propose some methodology / ideas for this.
Just in case you wanted to do it directly using matplotlib when you're plotting your data (imagemagick is great otherwise):
import Image
import matplotlib.pyplot as plt
import numpy as np
dpi = 100.0
im = Image.open('Dymaxion_map_unfolded.png')
width, height = im.size
fig = plt.figure(figsize=(width / dpi, height / dpi))
fig.figimage(np.array(im) / 255.0)
# Make an axis in the upper left corner that takes up 20% of the height and 30%
# of the width of the figure
ax = fig.add_axes([0, 0.7, 0.2, 0.3])
ax.plot(range(10))
plt.show()
ImageMagick can do the job, exactly the composite command. For the usage, check this url for the examples: http://www.imagemagick.org/Usage/annotating/#overlay
This sounds like something ImageMagick would be well suited for, esp. the -layers switch.

Set autoscale limits on plot to have buffer around all points

I would like to plot a set of points using pyplot in matplotlib but have none of the points be on the edge of my axes. The autoscale (or something) sets the xlim and ylim such that often the first and last points lie at x = xmin or xmax making it difficult to read in some situations.
This is more often problematic with loglog() or semilog() plots because the autoscale would like xmin and xmax to be exact powers of ten, but if my data contains only three points, e.g. at xdata = [10**2,10**3,10**4] then the first and last points will lie on the border of the plot.
Attempted Workaround
This is my solution to add a 10% buffer to either side of the graph. But is there a way to do this more elegantly or automatically?
from numpy import array, log10
from matplotlib.pyplot import *
xdata = array([10**2,10**3,10**4])
ydata = xdata**2
figure()
loglog(xdata,ydata,'.')
xmin,xmax = xlim()
xbuff = 0.1*log10(xmax/xmin)
xlim(xmin*10**(-xbuff),xmax*10**(xbuff))
I am hoping for a one- or two-line solution that I can easily use whenever I make a plot like this.
Linear Plot
To make clear what I'm doing in my workaround, I should add an example in linear space (instead of log space):
plot(xdata,ydata)
xmin,xmax = xlim()
xbuff = 0.1*(xmax-xmin)
xlim(xmin-xbuff,xmax+xbuff))
which is identical to the previous example but for a linear axis.
Limits too large
A related problem is that sometimes the limits are too large. Say my data is something like ydata = xdata**0.25 so that the variance in the range is much less than a decade but ends at exactly 10**1. Then, the autoscale ylim are 10**0 to 10**1 though the data are only in the top portion of the plot. Using my workaround above, I can increase ymax so that the third point is fully within the limits but I don't know how to increase ymin so that there is less whitespace at the lower portion of my plot. i.e., the point is that I don't always want to spread my limits apart but would just like to have some constant (or proportional) buffer around all my points.
#askewchan I just succesfully achieved how to change matplotlib settings by editing matplotlibrc configuration file and running python directly from terminal. Don't know the reason yet, but matplotlibrc is not working when I run python from spyder3 (my IDE). Just follow steps here matplotlib.org/users/customizing.html.
1) Solution one (default for all plots)
Try put this in matplotlibrc and you will see the buffer increase:
axes.xmargin : 0.1 # x margin. See `axes.Axes.margins`
axes.ymargin : 0.1 # y margin See `axes.Axes.margins`
Values must be between 0 and 1.
Obs.: Due to bugs, scale is not correctly working yet. It'll be fixed for matplotlib 1.5 (mine is 1.4.3 yet...). More info:
axes.xmargin/ymargin rcParam behaves differently than pyplot.margins() #2298
Better auto-selection of axis limits #4891
2) Solution two (individually for each plot inside the code)
There is also the margins function (for put directly in the code). Example:
import numpy as np
from matplotlib import pyplot as plt
t = np.linspace(-6,6,1000)
plt.plot(t,np.sin(t))
plt.margins(x=0.1, y=0.1)
plt.savefig('plot.png')
Obs.: Here scale is working (0.1 will increase 10% of buffer before and after x-range and y-range).
A similar question was posed to the matplotlib-users list earlier this year. The most promising solution involves implementing a Locator (based on MaxNLocator in this case) to override MaxNLocator.view_limits.

Resources