π Stanford CS231n κ°μλ₯Ό λ£κ³ κΈ°λ‘μ©λλ‘ μ 리νλ κ²μκΈμ λλ€.


prototypical algorithm that works really well and is perfectly suited on GPUs
dot products are all independent
whereas CPU might have to go in and step through sequentially and compute each of these elements one by one
convolution is the same



another problem in practice
solutions






with statement before forward pass β explicitly tell the framework to run this code on CPU or GPU




core written in C++
has python and Matlab bindings
good for training or finetuning feedforward classification models
often no need to write code
not used as much in research anymore, but still popular for deploying models
convert data (into HDF5 or LMDB ...) β Define network(prototxt) β define solver (prototxt - defines learning rate, optimization ...) β train
good for feedforward networks
good for finetuning existing networks
train models without writing any code
python interface is pretty useful
can deploy without python
need to write C++ / CUDA for new GPU layers
not good for recurrent networks
cumbersome for big networks (GoogleNet, ResNet)


x, y, w1, w2 and creating tf.placeholder projects
x and w1 and then do tf.maximum() to do a ReLU nonlinearity β another matrix multiplication to compute output predictionsy
w1 and w2


session.run() to actually execute some part of the graphloss: tells which part of the graph we want as output (in this case, tell that we want to compute loss and grad1 and gradw2
session.run() to compute the loss and the gradients
rather than w1 w2 being placeholders, define them as variables
variable is a value that lives inside the graph β persist inside the graph across differnt times when you run graph
also, we should initialize them! β pass tf.random_normal() to tell the TensorFlow how we want them to be initialized (this is not actually initializing them)

because weights live inside the graph, update also needs to be an operation inside the graph
- use assign() to mutate the variable inside the computational graph

we need to run the graph once with special incantation to tell TensorFlow to set up these variables that are in the graph
now we can run the graph over and over again
now we're only feeding in the data and labels x and y
ask the TensorFlow to compute the loss for us != train
problem

- we need to explicitly tell TensorFlow to perform those update operations
solution

- add new_w1 and new_w2 as outputs and tell the Tensorflow that we want to produce these values as outputs?
new_w1, new_w2 values are big tensors β meaning that we'll get the copying behavior between CPU and GPU at every iterationupdates has the data dependencies of new_w1 and new_w2updates value, we run the update operation
tf.train.GradientDesceptOptimizer([learning rate])optimizer.minimize(loss) is aware that variables w1 and w2 are marked as trainable by default β internally, it's adding node to the graph which will compute gradient of loss with respect to w1 and w2updates value 
tf.losses.mean_squared_error() does the L2 loss
tf.layers does this for youx and y, which are the placeholder for the data and labelstf.layers.dense() - sets up w1 and b1 with right shapes and uses Xavier initializer to set up an initialization strategy for thosetf.random_normal()



model.compile that builds the graph
model.fit to do the whole train procedure




are just like numpy arrays
2 layer network example




manual update of the weights using a learning rate and computed gradients
major difference between the PyTorch tensor and NumPy arrays - they run on GPU β to make this code run on GPU is using a different data type
torch.cuda.FloatTensor, rather than torch.FloatTensorx is variable, x.data is tensor, x.grad is another variable containing the gradient of the loss with respect to that tensor β x.grad.data is an actual Tensor containing those gradients


loss.backwards() for gradients
w1.grad.data




loss.backward() to get all gradients


optimizer.step() to update all the parameters of the model










tf.cond() (which is like an if statement)

tf.foldl()


