class: center, middle ### W4995 Applied Machine Learning # Advanced Neural Networks 04/27/20 Andreas C. Müller ??? FIXME add model inspection? FIXME add attention FIXME VGG images low res FIXME update with state-of-the-art instead of VGG16 FIXME my resnet is broken FIXME add finetuning with keras example FIXME dropout: make clear different for every sample in batch FIXME residual connections: plot the graph for the network I'm running --- # MNIST and Permuted MNIST ![:scale 90%](images/mnist_org.png) .smallest[ ```python rng = np.random.RandomState(42) perm = rng.permutation(784) X_train_perm = X_train.reshape(-1, 784)[:, perm].reshape(-1, 28, 28) X_test_perm = X_test.reshape(-1, 784)[:, perm].reshape(-1, 28, 28) ``` ] ![:scale 90%](images/mnist_permuted.png) --- # Fully Connected vs Convolutional .tiny[ .left-column[ ```python model = Sequential([ Dense(512, input_shape=(784,), activation='relu'), Dense(10, activation='softmax'), ]) model.compile("adam", "categorical_crossentropy", metrics=['accuracy']) ``` ``` _____________________________________________________ Layer (type) Output Shape Param # ===================================================== dense_7 (Dense) (None, 512) 401920 _____________________________________________________ dense_8 (Dense) (None, 10) 5130 ===================================================== Total params: 407,050 Trainable params: 407,050 _____________________________________________________ ``` ] ] -- .tiny[ .right-column[ ```python num_classes = 10 cnn = Sequential() cnn.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape)) cnn.add(MaxPooling2D(pool_size=(2, 2))) cnn.add(Conv2D(32, (3, 3), activation='relu')) cnn.add(MaxPooling2D(pool_size=(2, 2))) cnn.add(Flatten()) cnn.add(Dense(64, activation='relu')) cnn.add(Dense(num_classes, activation='softmax')) ``` ``` _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_1 (Conv2D) (None, 26, 26, 32) 320 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 11, 11, 32) 9248 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 5, 5, 32) 0 _________________________________________________________________ flatten_1 (Flatten) (None, 800) 0 _________________________________________________________________ dense_9 (Dense) (None, 64) 51264 _________________________________________________________________ dense_10 (Dense) (None, 10) 650 ================================================================= Total params: 61,482 Trainable params: 61,482 _________________________________________________________________ ``` ] ] --- # Training curves .left-column[ ## Original Data ![:scale 90%](images/mnist_org_curve.png) ] -- .right-column[ ## Shuffled Data ![:scale 90%](images/mnist_perm_curve.png) ] Any algorithm that doesn't take 2d layout into account is invariant to shuffling of pixels! (including anything in sklearn!) --- ![:scale 35%](images/carpet_snake.png) --
![:scale 22%](preview/snek_0_1271.jpeg) ![:scale 22%](preview/snek_0_3411.jpeg) ![:scale 22%](preview/snek_0_4863.jpeg) ![:scale 22%](preview/snek_0_5876.jpeg) ![:scale 22%](preview/snek_0_9549.jpeg) ![:scale 22%](preview/snek_0_4484.jpeg) ![:scale 22%](preview/snek_0_6377.jpeg) ![:scale 22%](preview/snek_0_4599.jpeg) --- # Data Augmentation - Rotation - Random crops - Mirroring - ... Make sure these reflect realistic and relevant variability! --- class: smaller # Image data augmentation with Keras ## https://keras.io/preprocessing/image/ ```python datagen = ImageDataGenerator( featurewise_center=True, featurewise_std_normalization=True, rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, horizontal_flip=True) # compute quantities required for featurewise normalization # (std, mean, and principal components if ZCA whitening is applied) datagen.fit(x_train) # fits the model on batches with real-time data augmentation: model.fit_generator(datagen.flow(x_train, y_train, batch_size=32), steps_per_epoch=len(x_train) / 32, epochs=epochs) ``` .smaller[ Also check [``flow_from_directory``](https://keras.io/preprocessing/image/). ] --- class: center, middle # Interpreting Neural Networks --- # Deconvolution .center[ ![:scale 100%](images/deconvolution_1.png) ] https://www.cs.nyu.edu/~fergus/papers/zeilerECCV2014.pdf ??? If you do it on natural images, you get something like this. This is one of the standard neural networks trained on image net dataset. So you can look at the filters in the input layer and because they're in image space, you can just visualize them. Here, this network has 9 filters in the first layer. If you look at the higher layers, if you want to see the filters, it's kind of hard, because they don't work on the input space, they work on the space created by these filters. But you can kind of try to project them down into the original image. And if you do that, then you get something like these. So this is sort of a visualization of what the second layer learned, this is sort of what they try to detect in the input. And for each of these, here, you can see the patches in the training set that most corresponded to them. --- class: center, middle ![:scale 100%](images/deconvolution_2.png) ??? The goal is that with each layer going up, it learns more and more abstract things. And so these are different units in the dataset and what they correspond to. This network learned to detect people even though there’s no person class in image net. --- class: center, middle ![:scale 100%](images/deconvolution_3.png) ??? If you go even deeper into the network, you can see that the units correspond to even more abstract things. These are all learned for the class of image classification. So this was just trained on the output, there was no information about the location of anything in the image, it was just trained. The dogs in these images are of different breeds and different vehicles, and so on. So there was never any location information in the training, but it's still picked up a lot of things. --- class: middle ![:scale 100%](images/distill-feature-vis.png) .smaller[https://distill.pub/2017/feature-visualization/] ??? This is a paper on feature visualization in neural networks. This is from Google net, also trained on the same set as image net. What they’re doing is they’re taking the network, they’re fixing the activation in a particular feature map and then they do backpropagation through the network to adjust the input image so that this particular feature map is most activated. This way, you want to create an image that activates this particular feature map or particular filter the most. This is one of the papers in a series of papers about how to restrict gradient descent on the input image to get some nice outputs. These are deeper into the network. In the beginning, it’s like edges of different frequencies and orientations, then you get something like textures, which are already quite rich, and then you get the larger textures, and then you get sort of more object like things and if you go further up, you get something that is very close to object. This sort of allows you to try to understand what the higher layers of these networks detect and it's quite interesting because a lot of these become quite specific. And this is all learned in a completely supervised way so the only feedback that the model got was learning to label these images correctly. But we get very fine-grained features in the network. --- class: middle # Drop-out ??? Drop out is a technique that’s relatively new compared to all the other things. It's a particular way to regularize the network, which cannot be done with scikit-learn. --- # Drop-out Regularization .center[ ![:scale 75%](images/dropout_reg.png) ] ??? For each sample, during training, you actually remove certain hidden nodes. So basically, you just X out the activations. You do this every time you trade over a training sample anew. So, this will be different for every example. The idea at the very high level is to add noise into the training procedure so that you basically make it harder to overfit. Since you drop out these parts, it gets much harder for the model to learn the training set by heart because you always remove different information. The goal is that you then learn weights that are more robust and since you're trying to prevent overfitting that possibly generalizes better. The dropout rate is often pretty high, sometimes it 50%, which means you set 50% of your units to zero. This is only during learning. You only want to add noise in the learning process. When you want to do predictions, you use all the weights but down weight them by the drop out rate. Here, we're not only perturbing the input image, but we're also perturbing the hidden units in a very particular way. As it turns out that actually works much better than just adding noise to the input. -- .smallest[ - https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf - Rate often as high as .5, i.e. 50% of units set to zero! - Predictions: use all weights, down-weight by 1 - dropout rate ] ??? - Randomly set activations to zero. Drop out is a very successful regularization technique developed in 2014. It is an extreme case of adding noise to the input, a previously established method to avoid overfitting. Instead of adding noise, we actually set given inputs to 0. And not only on the input layer, also the intermediate layer. For each sample, and each iteration we pick different nodes. Randomization avoids overfitting to particular examples. --- class:spacious #Ensemble Interpretation - Every possible configuration represents different network. - With p=.5 we jointly learn `$\binom{n}{\frac{n}{2}}$` networks - Networks share weights - For last layer dropout: prediction is approximate geometric mean of predictions of sub-networks. ??? --- #Implementing Drop-Out .smaller[ ```python from keras.layers import Dropout model_dropout = Sequential([ Dense(1024, input_shape=(784,), activation='relu'), Dropout(.5), Dense(1024, activation='relu'), Dropout(.5), Dense(10, activation='softmax'), ]) model_dropout.compile("adam", "categorical_crossentropy", metrics=['accuracy']) history_dropout = model_dropout.fit(X_train, y_train, batch_size=128, epochs=20, verbose=1, validation_split=.1) ``` ] ??? --- class:spacious # When to use drop-out - Avoids overfitting - Allows using much deeper and larger models - Slows down training somewhat - Wasn’t able to produce better results on MNIST (I don’t have a GPU) but should be possible ??? This is basically a regularizer. You're can learn much, much bigger networks with drop out so you can do deeper and wider networks without overfitting. That was the original intent. It slows down training even for the same size because you basically zero out a portion of the weights and these weights will not be updated. And so you need to do more iterations before you've learned all the weights. The question was, can we paralyze over different networks. It's not really implemented as different networks, it's more helpful to think of it as different networks. There are way too many networks as to store them separately. Generally, drop out is one of the techniques that people use that usually improve generalization and decrease overfitting. Another technique that you should look up is residual networks. It’s another generic strategy to speed up training and it allows to learn deeper networks. Not all state of the art neural networks you will see use drop out, but some of them might. And similarly, you will see some that use residual networks or batch normalization. There’s basically a toolbox of different tricks that people use and plot together to get good networks. Another technique that is often used with neural networks is augmenting the training data. So adding noise to training data, or changing the training data in some way so that you get more data is something that is often very helpful. We'll talk about images next. With natural images, you can flip it on the y-axis and it will still semantically be the same image unless you want to do OCR. And so if you do that, you just doubled the size of your training set. And for neural networks, the bigger training set, the better. If you do something like add noise, this actually gives you an infinite sized training set because every time you see a sample, you add noise in a different way and so you on the fly, generate arbitrarily big training datasets. Drop out is sort of a way to do this generically and do this on the hidden layer. But if you have domain knowledge, like for images, and you can do this in a way that's specific to the domain, then that is often more helpful. Another thing that is used with images, for example, is looking at different crops/scales of the image. So if you can crop your image in different ways, like 3 pixels to left and 3 pixels to the right and each of them is a new training sample, this way, you can also get infinitely many samples. Obviously, they're all correlated but it's better than just using the same sample over and over and makes overfitting harder. And these are actually very, very important techniques. So if you look at state of the art models they will always use these techniques to augment the training dataset, because getting images is easy, for example, but getting labeled images is very hard.  If you're just doing classification and cropping it differently or rotating, it will not change the label. Unless your label is a person holding something in the left hand versus holding something in the right hand and then you know you need to switch the label. class: center, middle # Deep Residual Networks (ResNet) [He et. al. - Deep Residual Learning for Image Recognition (2015)](https://arxiv.org/pdf/1512.03385.pdf) ??? One that made quite a big jump in performance is deep residual networks. --- class:center,middle # Batch Normalization ??? The next thing I want to talk about is one more trick that we can use to improve learning called batch normalization. This is a heuristic people found that speeds up learning and often gives better results. The idea here is that you want the hidden units to be scaled well. So what this does is kind of trying to scale hidden units to zero mean unit variance and doing this per batch. --- # Problem ![:scale 90%](images/resnet-no-deep-nets.png) ??? We can't fit deep networks well - not even on training set! "vanishing gradient problem" - was motivation for relu, but not solved yet. The deeper the network gets, usually the performance gets better. But if you make your network too deep, then you can't learn it anymore. This is on CIFAR-10, which is a relatively small dataset. But if you try to learn a 56-layer convolutional, you cannot even optimize it on the training set. So basically, it's not that we can't generalize, we can't optimize. So these are universal approximators, so ideally, we should be able to overfit completely the training set. But here, if we make it too deep, we cannot overfit the training set anymore. It's kind of a bad thing. Because we can’t really optimize the problem. So this is sort of connected to this problem of vanishing gradient that it's very hard to backpropagate the error through a very deep net because basically, the idea is that the further you get from the output, the gradients become less and less informative. We talked about RELU units, which sort of helped to make this a little bit better. Without RELU units, you had like 4 or 5 layers, with RELU units, you have like 20 layers. But if you do 56 layers, it's not going to work anymore. --- #Batch Normalization .center[ ![:scale 80%](images/batch_norm.png) ] .smallest[ [Ioffe, Szegedy: Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift](https://arxiv.org/abs/1502.03167) ] ??? Another relatively recent advance in neural networks is batch normalization. The idea is that neural networks learn best when the input is zero mean and unit variance. We can scale the data to get that. But each layer inside a neural network is itself a neural network with inputs given by the previous layer. And that output might have much larger or smaller scale (depending on the activation function). Batch normalization re-normalizes the activations for a layer for each batch during training (as the distribution over activation changes). The avoids saturation when using saturating functions. To keep the expressive power of the model, additional scale and shift parameters are learned that are applied after the per-batch normalization. --- # Convnet with Batch Normalization .smaller[```python from keras.layers import BatchNormalization num_class = 10 cnn_small_bn = Sequential() cnn_small_bn.add(Conv2D(8, kernel_size=(3, 3), input_shape=input_shape)) cnn_small_bn.add(Activation("relu")) cnn_small_bn.add(BatchNormalization()) cnn_small_bn.add(MaxPooling2D(pool_size=(2, 2))) cnn_small_bn.add(Conv2D(8, (3, 3))) cnn_small_bn.add(Activation("relu")) cnn_small_bn.add(BatchNormalization()) cnn_small_bn.add(MaxPooling2D(pool_size=(2, 2))) cnn_small_bn.add(Flatten()) cnn_small_bn.add(Dense(64, activation='relu')) cnn_small_bn.add(Dense(num_classes, activation='softmax')) ```] ??? very small to make it fit on a slide --- # Learning speed and accuracy .center[![:scale 80%](images/learning_speed.png) ] ??? FIXME label axes! The solid lines are with batch normalization and the dotted lines are without batch normalization. You can see the learning is much faster and also gets to a better accuracy. --- # For larger net (64 filters) .center[![:scale 80%](images/learning_speed_larger.png) ] ??? FIXME label axes Here's the same thing with a larger network where we have 64 filters instead of 8. This learns even faster and learns to overfit really well. --- # Problem ![:scale 90%](images/resnet-no-deep-nets.png) ??? We can't fit deep networks well - not even on training set! "vanishing gradient problem" - was motivation for relu, but not solved yet. The deeper the network gets, usually the performance gets better. But if you make your network too deep, then you can't learn it anymore. This is on CIFAR-10, which is a relatively small dataset. But if you try to learn a 56-layer convolutional, you cannot even optimize it on the training set. So basically, it's not that we can't generalize, we can't optimize. So these are universal approximators, so ideally, we should be able to overfit completely the training set. But here, if we make it too deep, we cannot overfit the training set anymore. It's kind of a bad thing. Because we can’t really optimize the problem. So this is sort of connected to this problem of vanishing gradient that it's very hard to backpropagate the error through a very deep net because basically, the idea is that the further you get from the output, the gradients become less and less informative. We talked about RELU units, which sort of helped to make this a little bit better. Without RELU units, you had like 4 or 5 layers, with RELU units, you have like 20 layers. But if you do 56 layers, it's not going to work anymore. Even it's not going to work anymore, even on the training set. So this has been like a big problem. And it has a surprisingly simple solution, which is the RES-NET layer. --- class: middle # Residual Neural Networks --- class: center # Solution ![:scale 50%](images/residual-layer.png) `$$\text{out} = F(x, \{W_i\}) + x \quad \text{ for same size layers}$$` -- `$$\text{out} = F(x, \{W_i\}) + W_sx \quad \text{ for different size layers}$$` -- `$$F(x) = \text{out} - x \quad \text{learing the residual}$$` ??? instead of learning a function. learn the difference to identity. if sizes different, add linear projection. Here's how the residual layer looks like. And the idea is, let's say you have a bunch of weight layers, instead of learning a function, we learn how the function is different from the identity. So you're not trying to model the whole relationship between x and y, you want to model how is y different from x. In practice, what happens is you have multiple weight layers, usually like 2, and you have skip connection that gives the identity from before these layers to after these layers. So basically, if you set these weights all to zero, you have a pass-through layer. And this allows information to be back-propagated much more easily because you have all these identity matrices, so something always gets backpropagated. So this obviously only works if y and x have the same shape. So in CNNs, often the convolutional layers have sort of the same shape. But then you also have max-pooling layers. And so what you can do is, instead of having the identity, you use a linear transformation. And this way, the gradients can propagate better. So just seems like a very simple idea but people have tried it before and it really made a big difference. --- class: center, middle ![:scale 25%](images/resnet-architecture.png) ??? dotted lines are linear projection, others are identity. MTG19, which a state of the art neural network before and these are all the layers. Next to it is a 34 layered, convolutional neural network. And then is the residual network. For each pair of two layers, you add in a skip connection. This black arrow is just an identity mapping because things are the same size. If there's pooling, there's this dashed arrow, which is a linear transformation. But basically, they're sort of a pathway that allows you to project the identity from the very beginning to the very end. Or from the output signal you get back towards the beginning. --- class: center, middle ![:scale 100%](images/resnet-success.png) ??? Here’s the result. The solid line is the training error and the bold line is the test error. The lines are depicted over the number of iterations. So what you can see here is the 18 layers works well than the 34 layers. And the training set is worse than the test set everywhere. But with the 34 layers, even the training set can’t beat the test set of the 18 layers. The next one is exactly the same architecture, but we put in all these identity matrices. And now we can see that the 18 layer is pretty unchanged. But the 34 layer is now actually better than the 18 layers. And in particular, we can overfit the dataset a little bit. This is a much better result than before. And when you publish this, this was state of the art and quite a big jump. --- class: center ![:scale 70%](images/resnet-results.png) -- This was Dec 2015. Current state-of-the-art: 11.5% top-1 error https://paperswithcode.com/sota/image-classification-on-imagenet (and this is less relevant as benchmark) ??? uses batch normalization and dropout. 152 layers is a whole lot of layers. ResNet is by Microsoft. So after this came out, people in Google stole the ResNet trick from Microsoft and then they got better. So residual networks become widely used after they published this. --- # ResNets in Keras .smallest[ Requires functinal API: https://keras.io/getting-started/functional-api-guide/ ```python from keras.layers import Input, Dense from keras.models import Model # This returns a tensor inputs = Input(shape=(784,)) # a layer instance is callable on a tensor, and returns a tensor x = Dense(64, activation='relu')(inputs) x = Dense(64, activation='relu')(x) predictions = Dense(10, activation='softmax')(x) # This creates a model that includes # the Input layer and three Dense layers model = Model(inputs=inputs, outputs=predictions) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(data, labels) # starts training ``` ] --- # CNN with Functional API .tiny[ .left-column[ ```python from keras.layers import Input, Conv2D, MaxPooling2D, Flatten from keras.models import Model num_classes = 10 inputs = Input(shape=(28, 28, 1)) conv1_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(inputs) conv1_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv1_1) maxpool1 = MaxPooling2D(pool_size=(2, 2))(conv1_2) conv2_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(maxpool1) conv2_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv2_1) maxpool2 = MaxPooling2D(pool_size=(2, 2))(conv2_2) flat = Flatten()(maxpool2) dense = Dense(64, activation='relu')(flat) predictions = Dense(num_classes, activation='softmax')(dense) model = Model(inputs=inputs, outputs=predictions) ``` ] .right-column[ ``` _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_3 (InputLayer) (None, 28, 28, 1) 0 _________________________________________________________________ conv2d_9 (Conv2D) (None, 28, 28, 32) 320 _________________________________________________________________ conv2d_10 (Conv2D) (None, 28, 28, 32) 9248 _________________________________________________________________ max_pooling2d_5 (MaxPooling2 (None, 14, 14, 32) 0 _________________________________________________________________ conv2d_11 (Conv2D) (None, 14, 14, 32) 9248 _________________________________________________________________ conv2d_12 (Conv2D) (None, 14, 14, 32) 9248 _________________________________________________________________ max_pooling2d_6 (MaxPooling2 (None, 7, 7, 32) 0 _________________________________________________________________ flatten_3 (Flatten) (None, 1568) 0 _________________________________________________________________ dense_13 (Dense) (None, 64) 100416 _________________________________________________________________ dense_14 (Dense) (None, 10) 650 ================================================================= Total params: 129,130 Trainable params: 129,130 Non-trainable params: 0 _________________________________________________________________ ``` ] ] --- class: compact # Adding Skip connections .tiny[ .left-column[ ```python from keras.layers import Input, Conv2D, MaxPooling2D, Flatten from keras.models import Model num_classes = 10 inputs = Input(shape=(28, 28, 1)) conv1_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(inputs) conv1_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv1_1) maxpool1 = MaxPooling2D(pool_size=(2, 2))(conv1_2) conv2_1 = Conv2D(32, (3, 3), activation='relu', padding='same')(maxpool1) conv2_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv2_1) # Actually doesn't work, this net is too small skip2 = add([maxpool1, conv2_2]) maxpool2 = MaxPooling2D(pool_size=(2, 2))(skip2) flat = Flatten()(maxpool2) dense = Dense(64, activation='relu')(flat) predictions = Dense(num_classes, activation='softmax')(dense) model = Model(inputs=inputs, outputs=predictions) ``` ] .right-column[ .tiniest[ ``` _________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ========================================================================================= input_14 (InputLayer) (None, 28, 28, 1) 0 _________________________________________________________________________________________ conv2d_57 (Conv2D) (None, 28, 28, 32) 320 input_14[0][0] _________________________________________________________________________________________ conv2d_58 (Conv2D) (None, 28, 28, 32) 9248 conv2d_57[0][0] _________________________________________________________________________________________ max_pooling2d_23 (MaxPooling2D) (None, 14, 14, 32) 0 conv2d_58[0][0] _________________________________________________________________________________________ conv2d_59 (Conv2D) (None, 14, 14, 32) 9248 max_pooling2d_23[0][0] _________________________________________________________________________________________ conv2d_60 (Conv2D) (None, 14, 14, 32) 9248 conv2d_59[0][0] _________________________________________________________________________________________ add_11 (Add) (None, 14, 14, 32) 0 max_pooling2d_23[0][0] conv2d_60[0][0] _________________________________________________________________________________________ max_pooling2d_24 (MaxPooling2D) (None, 7, 7, 32) 0 add_11[0][0] _________________________________________________________________________________________ flatten_14 (Flatten) (None, 1568) 0 max_pooling2d_24[0][0] _________________________________________________________________________________________ dense_35 (Dense) (None, 64) 100416 flatten_14[0][0] _________________________________________________________________________________________ dense_36 (Dense) (None, 10) 650 dense_35[0][0] ========================================================================================= Total params: 129,130 Trainable params: 129,130 Non-trainable params: 0 _________________________________________________________________________________________ ``` ] ] ] --- class: center, middle ## https://keras.io/applications/
Model
Size
Top-1 Accuracy
Top-5 Accuracy
Parameters
Depth
Xception
88 MB
0.790
0.945
22,910,480
126
VGG16
528 MB
0.713
0.901
138,357,544
23
VGG19
549 MB
0.713
0.900
143,667,240
26
ResNet50
98 MB
0.749
0.921
25,636,712
-
ResNet101
171 MB
0.764
0.928
44,707,176
-
ResNet152
232 MB
0.766
0.931
60,419,944
-
ResNet50V2
98 MB
0.760
0.930
25,613,800
-
ResNet101V2
171 MB
0.772
0.938
44,675,560
-
ResNet152V2
232 MB
0.780
0.942
60,380,648
-
InceptionV3
92 MB
0.779
0.937
23,851,784
159
InceptionResNetV2
215 MB
0.803
0.953
55,873,736
572
MobileNet
16 MB
0.704
0.895
4,253,864
88
MobileNetV2
14 MB
0.713
0.901
3,538,984
88
DenseNet121
33 MB
0.750
0.923
8,062,504
121
DenseNet169
57 MB
0.762
0.932
14,307,880
169
DenseNet201
80 MB
0.773
0.936
20,242,984
201
NASNetMobile
23 MB
0.744
0.919
5,326,716
-
NASNetLarge
343 MB
0.825
0.960
88,949,818
-
??? Here are all the things that are inside Keras. Inception is created by Google by copying from Microsoft. These are pretty well-performing models but this list changes daily. --- class: middle # Transfer learning --- class: center # Transfer Learning .center[ ![:scale 80%](images/pretrained_network.png) ] .smaller[See http://cs231n.github.io/transfer-learning/] ??? - Train on “large enough” data. - Apply to new “small” dataset. - Take activations of last or second to last fully connected layer. Often we have a small but specific image dataset for a particular application. Training a neural net is not feasible unless we have tens of thousands or hundreds of thousands of images. However, if we have a convolutional neural net that was already trained on a large dataset that is similar enough, we can hope that the features it learned are also helpful for our task. The easiest way to adapt a trained network to a new task is to just apply it to our dataset and take the activations of the second to last or last layer. If the original task was rich enough – say 10000 different classes as in imagenet – these layers contain a lot of information about the image. We can then use these activations as features for another classifier like a linear model or smaller dense neural network. The main point is that we don’t need to retrain all the weights in the network. You can think of it as retraining only the last layer – the classification layer – of the network, while holding all the convolutional filters fixed. If they learned generic patterns like edges and patterns, these will still be useful for your task. You can download pre-trained neural networks for many architectures online. Using a pre-trained network is sometimes also known as transfer learning. This potentially doesn’t work with images from a very different domain, like medical images. What you do in transfer learning is you basically get rid of the last layer, you look at the second to last layer and you just use the representation in this layer as a feature representation. So this is basically a way to embed the image into vector space, similar to what word2vec did, only now we're embedding this whole image into space, and we get 4069-dimensional representation. People have tried to use neural networks for feature learning for many years, but it never really worked really well. What made this work really well in practice is, this is basically a supervised task, so this whole thing is learned to do this classification in these 1000 classes. So this is a very specific task to optimize, the model tries to be discriminative with respect to these classes. But on the other hand, these 1000 classes spend a whole variety of natural images, a whole variety of different kinds of objects, and scenes, and everything so that to actually perform well on this task, you need a representation of the world that is somewhat generic. So the hope is that these 4000-dimensional feature vector doesn't encode only information about the 1000 classes that we are actually interested in here but more general information about the image. Last time, I showed you neurals that reactive to faces, clothing, there are no categories like faces or clothing in the dataset but still, there are some filters that respond to that. This has been very successful. The reason why we want to do this is it's very hard to train CNNs, and you need a lot of data. So if you have a specific image recognition task, it's very likely that the things you're interested in are not one of the 1000 classes, because you have mostly different breeds of dogs. But you probably also don't have a million training images to actually train an architecture like this yourself. And you really need a lot of training data to make this work. So here, what we're doing is we will use this network learned on this very large, very generic database to learn representation. And then we can use as a representation for different tasks. And this is what you're supposed to do in the last task in the homework. --- class: spacious # Ball snake vs Carpet Python .center[ ![:scale 100%](images/ball_snake_vs_python.png) ] ??? I want to now classify ball snakes and carpet pythons. --- .smaller[ ```python import flickrapi import json flickr = flickrapi.FlickrAPI(api_key, api_secret, format='json') json.loads(flickr.photos.licenses.getInfo().decode("utf-8")) def get_url(photo_id="33510015330"): response = flickr.photos.getsizes(photo_id=photo_id) sizes = json.loads(response.decode('utf-8'))['sizes']['size'] for size in sizes: if size['label'] == "Small": return size['source'] get_url() ids = search_ids("ball snake", per_page=100) urls_ball = [get_url(photo_id=i) for i in ids] from urllib.request import urlretrieve import os for url in urls_carpet: urlretrieve(url, os.path.join("snakes", "carpet", os.path.basename(url))) ```] ??? --- .center[ ![:scale 80%](images/carpet_python_snake.png) ] ??? I get 100 carpet snake pictures and 100 ball snake pictures from Flickr. This would be way too small of a training dataset to train a convolutional neural network. If we extract features using an existing convolutional neural network, we can learn something like a linear classifier on top of these representations. There is noise in the dataset and similar looking things. --- # Extracting Features using VGG .smaller[ ```python from keras.preprocessing import image X = np.array([image.img_to_array(img) for img in images_carpet + images_ball]) # load VGG16 model = applications.VGG16(include_top=False, weights='imagenet') # preprocessing for VGG16 from keras.applications.vgg16 import preprocess_input X_pre = preprocess_input(X) features = model.predict(X_pre) print(X.shape) print(features.shape) features_ = features.reshape(200, -1) ``` ``` (200, 224, 224, 3) (200, 7, 7, 512) ```] ??? VGG16 like each convnet has particular input requirements, for example 224x224 images. Include top=false means I don’t want the last layer which does the 1000 class classification. I need to load the images and convert them into an array in the shape that keras wants it. So you need to make sure that the input has the right representation. You need to also make sure that it's preprocessed in the same way as all the images that VGG16 was trained with. VGG16 was trained in a particular way that image net was cropped. These were 224x224 images, so you need to make sure that whatever you input into your model is 224x224. And the way you bring it to this should probably be the same way it was done for the whole training set. So here for each of the applications, there's also a preprocess input, which basically does exactly the same preprocessing as what was done for the training of the network. And this is really important. Model.predict will take a while for a big dataset because you need to run through these whole neural networks. X_pre is after the preprocessing, I have 100 images of snakes of each kind, it's 224x224x3 and this the right input for the model. And then after I call predict, after all these convolutional layers, I get 7x7 feature map, and there's 512 of them. You could probably also do more smarter things, you could look at the output of multiple layers, like the last layer, the second to last layer, or something like that, I just used the last layer and just flatten everything to get out of it. So here's there’s a little bit of input structure left so still a 7x7 image, but I just ignored the image structure. --- # Classification with LogReg .smaller[ ```python from sklearn.linear_model import LogisticRegressionCV lr = LogisticRegressionCV().fit(X_train, y_train) print(lr.score(X_train, y_train)) print(lr.score(X_test, y_test)) from sklearn.metrics import confusion_matrix confusion_matrix(y_test, lr.predict(X_test)) ``` ``` 1.0 0.82 array([[24, 1], [ 8, 17]]) ```] ??? On the training set, I get 100% accuracy and on the test set, I get 82% accuracy. It's a balanced dataset, so the chance is 50%. If I did any classification directly on the image, it would be impossible basically. These images are so high dimensional and so varied, that it will be impossible to learn classifier on these images directly. If you look at this image, it's 224x224x3 which means it's like about 100,000, if you think of it as a feature vector. So you would have 100,000 features and 200 examples and training a linear model on this, in particular given how the data is represented is basically hopeless. But using this pre-trained convolutional neural network, we can actually do something quite successful here on this tiny dataset. And this is how convolutional networks are very commonly used in practice. Just select a relatively small dataset that is specific to your domain and you use a pre-trained neural network as a feature extraction mechanism. --- #Finetuning .center[ ![:scale 90%](images/finetuning.png) ] ??? - Start with pre-trained net - Back-propagate error through all layers - “tune” filters to new data. A more complicated variant of this is to load a network trained on some other dataset, and replace the last layer with your classification task. Instead of training only the last layer, we can also keep training all the previous layers, backpropagating the gradient through the network and adjusting the previously learned filters for our task. You can think of this as warm-starting a neural network from one that was trained on another dataset. If you do that, we often want to train the last layer a little bit before we backpropagate through the network. Otherwise the random initialization of the last layer might destroy the filters that we used for initialization. Another option is, instead of just taking the output representation by the network, we can do fine tuning. In fine-tuning, you keep the network but you don't only use it for feature extraction, you basically use the weights learned on the different dataset as initialization. You learn all the weights, you throw away the last layer, because that was specific to the classification task you had. And now you learn like a linear classifier on top, but you not only learn the weight of the linear classifier in the back, you also backpropagate the error through the whole network. Usually, you want to do like a little bit of a burn at the beginning where you tune just the last layer, but then you basically keep learning the whole network, it's probably not going to change the filters too much but it's going to adjust the network to your specific task. But it's much, much easier than trying to learn from scratch. The problem with is that if you have too little data, you can overfit your data very easily. Neural networks have very many parameters so if you try to train them or even fine tune them on a very small dataset, then you're just going to overfit. So depending on dataset size and how similar to image net may be, either fine-tuning or just extracting the last layer might be the best way to go forward. You should really think about convolutional neural networks as doing something fundamentally different than fully connected networks or any other classifier because they use the 2d structure of the input. If you think of the MNest digits, if you shuffled all the pixels in the same way for all of the images, any classifier that we looked at so far, will have exactly the same result. The ordering of the pixels is completely ignored by fully connected neural networks, random forest, SVM, and linear model. If you shuffled all the pixels in the same way for all images, it would look like complete garbage and it would be impossible for a human to actually classify them. The machine learning algorithms do exactly the same thing if they’re not shuffled. They completely ignore all the neighborhood structure and they’re similarly accurate. On convolutional neural networks, it really makes use of this neighborhood structure of the networks. So if we shuffled all the pixels, the convolutional network will completely fail because the neighboring pixels don't have anything to do with each other anymore and the convolutional network could not learn anything. So this is sort of a crucial difference between how the convolutional networks work versus how any of the other classifiers work. They really make use of the topology of the input space to this structure. And if you didn't do that, so for MNest you could do something even if you ignore the pixels structure, you will not get anything. So it's really important to use something that's aware of the image structure. --- class: center, middle # Recurrent Neural Networks ??? Recurrent networks are usually used for time series, or generally for sequential data. --- class: center, middle ![:scale 100%](images/recurrent-neural-net.png) .smallest[ Images from http://colah.github.io/posts/2015-08-Understanding-LSTMs/ ] ??? In RNN, we have an input, hidden layer and an output. Basically, the hidden layer is connected to itself. So at the first time step, you get some input here, compute the hidden layer, and get some output. At the second time step, you get some input again and compute some output, but you can also look back to the last hidden layer state. But the weights are all shared. So the matrix, U, V, and W are constant all the time. This is done if you have a time series or any series that you want to tag everything in the series. So for example, in NLP people like to know is something a noun or a verb. So if you feed in a sentence, then for each word it would say what kind of word it is, as a part of speech tagging. Or if you want to make a prediction over time, if you have an input signal that evolves over time, and you want to predict an output signal, then you could also use that. Here basically, this works if you have two parallel sequences and if you want an output for each element in the input sequence. The problem is that if you have long term dependencies, this doesn't work very well. If the output here depends on the input way back then the network will have forgotten about this. Because you always have the same weight matrix V and it just propagates information forward and forward. It's very hard for a network to remember things that happened previously. So as to overcome this problem, people started using LSTMs. --- class: center, middle ![:scale 100%](images/LSTM.png) .smallest[[Hochreiter, Schmidhuber - Long Short-Term Memory (1997)](http://www.bioinf.jku.at/publications/older/2604.pdf)] ??? Which stands for long short term memory. This is from 1997. It was ignored for 10 years. But now it's all the rage. The idea is that now the hidden layer looks like this. The idea is that you have multiple parts of this hidden layer, which influence how you use the last state, how you use the input, and how you're going to propagate it forward. Here at the current time step, there's weight matrix Ft, this is a multiplicative influence on the last Ct, which is sort of one part of the memory. There's two parts of the memory, Ct and Ht. Lt is how much the current activation influence Ct. TanH is a layer that's the new activation of Ct. The final output gate that says how much should Ct influence the output in H. So basically, Ct is sort of a control stream, and Ht is the activations. So instead of having one hidden layer, you have the hidden layers made out of some memory, some forget, some waiting and some gating. So each layer would be replaced by one of these. --- class: center, middle ![:scale 100%](images/GRU.png) .smallest[[Cho et. al. - Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation(2014)](https://arxiv.org/pdf/1406.1078)] ??? Since they're so complicated, a friend of mine came up with this thing called the GRU which is simpler. Here, you only have a single string of hidden data, and you have something like a forget gate. The idea between these forget gates is you want to be able to propagate error more easily and they are something similar to shortcut connections over time. Basically, if there's no influence coming from Xt on σ and σ channel, then the information just flows through directly. And this basically is similar to the shortcut units in the RES-NET only like 20 years earlier. So here the idea is to allow backpropagation through more time by having some quite intricate structure. This a little bit faster and a little bit easier to understand. --- class: center, middle ![:scale 100%](images/lstm-unrolled.png) ??? But I think most people are using the LSTM these days. Each hidden layers basically replaced by one of these. So here, for each time step, you put in the LSTM layer that has these two streams of data coming from the last LSTM layer, and you produce an output. This is a state of the art for doing things like parts of speech tagging, or just predicting on time series or predicting on any kinds of series. This is pretty easy to do with keras or any other deep learning toolbox. Unfortunately, not that many problems have this form. Often you want to have interactions between sequences where they don't have the same length, for example, text. Also, they might have long term dependencies. So for example, if you want to translate German to English, the word that you say at the end, might depend on the word that was said in the beginning, and the other way around. So if I tried to do something like this, the output here might actually depend on the input later, in a sentence and so you can do it with this architecture. Also, they will have different lengths, everything is longer in German. --- class: center, middle ![:scale 100%](images/seq2seq.png) .smallest[[Sutskever et. al. - Sequence to Sequence Learning with Neural Networks (2014)](https://arxiv.org/pdf/1409.3215.pdf)] ??? Here, you have an input sequence, A, B, C, and you want to predict the sequence W, X, Y, Z. And so what you do is you start reading the input sequence token by token or word by word, in this example, you start reading A, B, and C and read the end of sentence. Once the model reads end of sentence, you start trying to predict. And then you predict, predict, predict until the model predicts end of sentence. For each new prediction step, you also feed in what was the output of the last step. And then again, you train this thing with backpropagation. It's called back progression through time, because you need to backpropagate along this whole sequence. The surprising thing about this is this actually works. --- class: center # Machine Translation ![:scale 45%](images/seq2seq-machine-translation.jpg) ??? This is how it looks in practice. This an example of machine translation taken from TensorFlow tutorial. This model is just trained doing backpropagation. And it learns to translate languages properly. This is how Google Translate works. The structure of the two sentences is quite similar. But these sentences are not aligned in any way. You just have an input sequence and an output sequence. It works for any 2 sequences basically. This is called sequence to sequence learning. With this architecture, you can learn to predict any arbitrary sequences. --- class: center # Question answering ![:scale 80%](images/general-qa.png) .smallest[[Chen et. al. - Reading Wikipedia to Answer Open-Domain Questions](https://arxiv.org/pdf/1704.00051v2.pdf) https://rajpurkar.github.io/SQuAD-explorer/] ??? These are actually training examples. There are datasets of questions and answers. The model is supposed to learn these using a context paragraph. Making this actually work is more than just doing a sequence to sequence but the main architecture, the main component, is a sequence to sequence. So here, it tries to predict from the question the answer using some context. This is actually from a training set but the model actually performs reasonably well on this. Of course, these networks need a lot of data to train, they take very long to train and you need to fiddle around with it a lot, you need to do things like batch normalization drop-out and so on and you need these weird LSTM layers. But there's a whole lot of research happening in this kind of space. People have been using recurrent neural networks also to learn word representations that are sort of more powerful than word2vec. --- # Adverserial Samples .center[ ![:scale 80%](images/adverserial.png) ] .smallest[
[Szegedy et. al.: Intriguing properties of neural networks](https://arxiv.org/abs/1312.6199) ] ??? Since convolutional neural nets are so good at image recognition, some people think they are pretty infallible. But they are not. There is this interesting paper about intriguing properties of neural networks, that introduces adverserial samples. Adverserial samples are samples that were created by an adversary or attacker to fool your model. Here, they changed images to be classified as Ostrich by AlexNet trained on imagenet. The picture on the left is change just slightly, and went from correctly classified to classified as Ostrich. This technique uses gradient descent on the input and requires access to all the weights in the network to create the samples. Given how high-dimensional the input space is, this is not very surprising from a mathematical perspective, but it might be somewhat unexpected. requires the weights, done by gradient descent. FIXME where should this go? --- class: middle # Questions ?


Home
Heroes
+
Heroes
Awakenings
Skins
The Forge
+
Soulstones
Forge
Runestones
Heroes Village
+
Furnace
Academy
Workshop
Credits
Settings
Dark Mode
Awakening Spoilers


An Open-Source Quality Measure Reference Implementation
Empowers healthcare providers to perform Meaningful Use quality measure reporting and promotes easier submission of quality measures to public health organizations
ONC has officially ended its role as the primary developer, manager, and sole governance entity for the open source tool called popHealth. Since 2013, it has worked to prepare for transitioning the development, management and governance to the open source community.
At this point, ONC is freezing code associated with the popHealth github branch and it is freezing the content of the website. This github repository will remain available in the near term for anyone in the community to use as a resource. This includes forking the code into a new independent project. ONC plans to maintain the popHealth listservs.
Several highly active members of the community have decided to work with the Open Source Electronic Health Record Alliance (OSEHRA) as the open source management-support entity for popHealth going forward. A repository of their version of the code can be found here: https://github.com/osehra/pophealth
ONC will still have a limited ongoing role in popHealth as outlined previously. We are very excited about the future of popHealth. If you have questions, please contact<EMAIL_ADDRESS>– DATE OF POSTING: 09/25/2014
Empowers healthcare providers to perform Meaningful Use quality measure reporting and promotes easier submission of quality measures to public health organizations
ONC has decided to transition popHealth to the open source community. A variety of resources describing this and supporting this can be found here.
| Feb/Mar 2014 | In February and March ONC held follow-up meetings with the stakeholder community to solicit feedback on the draft governance plan. |
|---|---|
| Jan 2014 | popHealth community attended an in-person meeting in Washington, DC on January 21st |
| Dec 2012 | popHealth v2.1 support for MU Stage 2 CQMs for Eligible Professionals – Completed |
| Jun 2012 | MU Stage 1 CQM performance presentation at the Government Health Information Technology conference. – Completed |
| CCDA XML Import Capability June 22, 2012 – Completed | |
| Mar 2012 | popHealth showcased at the Human Factors Conference: March, 12-14, 2012 – Completed |
| popHealth featured in John Halamka's blog | |
| Feb 2012 | Version 1.4 Webinar and new design – Completed |
| Jan 2012 | popHealth v1.4 Support for provider-specific features – Completed |


In this hangman style word guess game you will have to guess a reggaeton artist name, once a correct answer is achieved then the picture of the artist and their best latest song will appear on
Your score is: 0 !
You have: 10 lives left.
You have tried: ... so far.


We arrived in Savannah expecting to spend one night and head out in the morning en route to Jacksonville, FL. Once we pulled into Skidaway Island State Park however, we knew we had to stay longer! Driving in, it felt like we were in a jungle with spanish moss hanging from the trees. Each site is first come first serve, so you select your site when you get there. We found a fairly private pull through site (68) that was perfect for us. We were greeted by the nicest camp host who told us about a field nearby where dogs are allowed to run off leash. He also told us about the nearby restaurant on the island and informed us downtown Savannah was super dog-friendly as well. Um, sold! Wish we could have stayed longer!
Pros:
The proximity to Savannah, GA is awesome. We wanted to explore more of the city, but Nick was fighting off a cold so we pretty much hung around Skidaway for the 2 days we stayed. The surrounding area is really nice. There’s a Publix right by the state park as well as a cute little restaurant we ate at twice called the Village Bar and Grille. Everyone was really laid back and nice who worked at the park. The bathrooms were clean and fairly updated, and the washing machines were a welcome sight for me since these had been broken at the last place we stayed.
Cons:
It’s kind of hard to find the cons to this place! Maybe if we stayed longer we’d find them? There were mosquitoes, but they weren’t unbearable. We were there on the weekend so we didn’t check our cell signal too thoroughly so can’t speak much to that. However, our Verizon cell phones worked well for calls and texts, we just didn’t get online all that much.


| Post | Author | Date | Value | Votes |
|---|---|---|---|---|
| {{ post.title|truncatechars:80 }} | {{post.author}} | {{ post.created| date:"Y-m-d H:i" }} | {{post.pending_payout_value }} | {{post.active_votes|length }} Votes |
{% extends 'blog/base.html' %} {% block content %} {% with request.resolver_match.view_name as view_name %}
| Post | Author | Date | Value | Votes |
|---|---|---|---|---|
| {{ post.title|truncatechars:80 }} | {{post.author}} | {{ post.created| date:"Y-m-d H:i" }} | {{post.pending_payout_value }} | {{post.active_votes|length }} Votes |


Play live chess variants designed to practice specific chess skills.
Teach specific chess skills to your student or child using our two person interface. Our interactive mode allows two people to play together on the same screen, making it easy to use chessercizes as a powerful teaching tool.
The chessercizes curriculum is designed to teach mastery of basic chess fundamentals. Create an account to track progress through all 30 variants.


Herat’s Historical Sites Need Renovation: Officials
Herat officials said a portion of the budget has been allocated to maintain historical sites.
by Nasir SalehiMost of the historical places in the western province of Herat are on the verge of ruin due to inattention by the government, two local officials said, adding that the budget for renovation of historical sites is insufficient.
Herat has over 800 historical sites, according to local officials, and most of them are in need of care.
The Friday Mosque, Herat Citadel, Khwajah Abdullah Ansari Shrine, the Gawhar Shad Mausoleum, the minarets of Herat and the Malan bridge are among the famous historical sites in the province.
“The smallest amount of attention has been paid to Herat’s historical sites—compared to other places in Afghanistan—by the Ministry of Information and Culture,” said Arya Raufian, head of the Information and Culture Directorate in Herat. “Our budget for maintainance of these sites is zero this year.”
He said his office sent a letter to the Ministry of Information and Culture this year, identifying five historical places that will be ruined if they are not maintained.
Some of the historical sites are located in the city of Herat, while others are located in Guzara, Ghorian, Chasht and Kohsan districts.
Herat governor’s spokesman Jailani Farhad said that at least Afs170 million has been allocated to maintain historical places in the province.
“A survey has been conducted of the historical sites,” he said, “This has been shared with providers of national and international resources. We will try to find more resources to maintain historical sites.”
But some say a more thorough review of these locations is necessary.
“Some historical sites in Guzara district have been damaged due to rains and they are on the verge of destruction,” said Humayun Ahmadi, a Herat resident.


An Interactive Introduction To Quantum Computing Part 2
This is Part 2 of a two part series. In Part 1 I explained some of the basics of qubits, including the mysterious notions of phase and quantum interference. Here in Part 2, you will learn how quantum computers may one day be able to solve search problems faster than conventional computers.
Multiple qubits
Important: There is something really important I feel the need to emphasize as we start dealing with multiple qubits.
The blue disks introduced in Part 1 do not correspond to single qubits.
Each blue disk corresponds to a distinct state of the entire quantum system. If you are not sure what I mean by that, then please hang in there, it will hopefully become aparent very soon.
Controlled NOT
The Controlled NOT operator is a very simple but powerful two-qubit operator.
The Controlled NOT operator modifies the value of one qubit (the target qubit) based on the value of another qubit (the control qubit).
Specifically, the Controlled NOT operator flips the value of the target qubit if the control qubit has a value of 1.
For example: Suppose we have two qubits with an initial value of “11”. Let's use the left qubit as the control qubit and the right qubit as the target. Then the result of applying a Controlled NOT will be “10”. As usual, we represent this as “11 → 10”
Continuing with our choice of left qubit as control qubit and right qubit as target, there are four scenarios to consider for the Controlled NOT operator.
- 00 → 00 (i.e. no effect)
- 01 → 01 (i.e. no effect)
- 10 → 11 (i.e. target bit flips)
- 11 → 10 (i.e. target bit flips)
Quantum Entanglement
A combination of the Hadamard followed by a Controlled NOT can put two qubits into a state of “quantum entanglement”.
In what follows, we take a two qubit system in the state “00”, apply the Hadamard operation to the left qubit, and then use that left qubit as the control in a Controlled NOT of the right qubit:
Initial State
After applying a Hadamard to the left qubit
When you apply a Hadamard to the left qubit, that qubit goes into a superposition of 0 and 1. The right qubit is not touched and continues to have the value 0. So the pair of qubits goes into a superposition of 00 and 10.
After a Controlled NOT of the right qubit controlled by the left qubit
The Controlled NOT will leave the 00 state unchanged as the control qubit (left qubit) is 0.
When acting on the 10 state, the control qubit is 1, and so the target bit is flipped resulting in 11. So the pair of qubits goes into a superposition of 00 and 11.
Note that, if you were to measure the qubits while they are in this state, you would find that they are either both 0 or both 1. This sort of correlation between qubit values within a superposition is called “quantum entanglement”.
Why quantum entanglement is so special deserves an entire article of its own. For now, I am simply using entanglement to emphasise how quantum superposition can apply to the combined state of a number of qubits.
Arbitrary Logic Functions
In addition to the NOT operator that we have already seen, a quantum computer can implement the standard logic functions of AND and OR. From these, one can compute any function over a fixed number of bits.
The details are surprisingly fascinating and not as straight forward as you might expect. However, for the purposes of this article, I want you to trust me when I say it can be done. This will allow us to move more quickly to the even more fascinating topic of quantum search.
Before we can cover quantum search, there is one more quantum operator I need to introduce.
Controlled Phase Flip
Recall that the term phase, introduced in Part 1, refers to the arrow direction of a state.
The controlled phase flip is a multi qubit operator. It flips the phase of the states where all of the specified qubits have the value of 1.
More useful to us, however, is a generalised form of the controlled phase flip. It will flip the phase of the states where the target qubits have any specified combination of 1's and 0's.
Try it yourself:
Quantum Search
Imagine you are trying to crack an n-bit encryption key by brute force: i.e. by trying every one of the 2n possible values.
This is a classic needle in a haystack search problem.
You need to construct a function, called the oracle function, that takes a candidate value as input and returns true or false depending on whether or not the candidate is the correct key.
A conventional computer will need to evaluate the oracle function, on average, 2n-1 times.
By using Grover's algorithm, a quantum computer only needs to evaluate the oracle function less than √(2n) times.
Even if a conventional computer can compute the oracle function in a nanosecond, if the input was 64 bits long, then it would probably take hundreds of years for that conventional computer to find the answer. A quantum computer might possibly take just a few seconds. A conventional computer would have to evaluate the oracle function an average of 263 times, compared to just over four billion times for a quantum computer. It is likely however, at least in the early days of quantum computing, that individual operations on a quantum computer may be vastly slower than on a conventional computer. It may take a while before quantum computers ever get to solve a problem any faster than conventional computers.
For the extremely simple case where the input is only 2 bits, there are four possible answers. A conventional computer may need to test up to three of those possible values. (If it isn't the first three, then you can infer it must be fourth one without testing it.) As you will see below, a quantum computer can find the answer using a single invocation of the oracle function.
Quatum Search over 2 Qubits
First recall that the objective is to find the value of x for which the oracle function is true. For Gover's Search Algorithm to work, it is essential that the oracle function is true for only one value of x.
In the conventional descriptions of Gover's Search Algorithm, it is assumed that the the oracle function will flip the value of an “output” qubit when the input matches the desired result. It is a lot more convenient if we do away with the output bit, and instead flip the phase when the input matches the desired result.
Here are the steps to Gover's Search Algorithm for the very simple case of two bits.
- Start with the qubits in a superposition of all possible states: 00, 01, 10, and 11 (all with the same phase).
- Apply the oracle function once only.
- Apply a Hadamard operation to both qubits.
- Flip the phase of the 00 state.
- Apply a Hadamard operation to both qubits again.
- The resulting state is your desired answer (except that it's phase will be 180 degrees which you can safely ignore).
You can try it yourself below. The four possible oracle functions are labelled as fx, indicating that f is true for the value x.
Don't forget, you can safely ignore the final phase.
Don't forget, unlike what happens in the animation, all the states change simultaneously.
Beyond Quantum Search
The two bit search is a bit of a special case where the oracle function only needs to be invoked once. As the number of bits increases, it becomes necessary to invoke the oracle function multiple times. In fact it needs to be invoked ¼π√(2n) times.
While general quantum search techniques may seem quite impressive, even ¼π√(2n) gets very large very quickly.
All you have to do is double the number of bits to wipe out any advantages. For example, over a 128 bit search space, a quantum computer would need to evaluate the oracle function almost as many times as a conventional computer does over a 64 bit search space. Even at one evaluation per nanosecond, it would take hundreds of years to crack a 128 bit encryption key.
However, encryption keys commonly used for securing internet traffic (RSA keys) can be broken using a special purpose quantum algorithm. These encryption schemes rely on the difficulty of factoring very large numbers, something that can be easily done on a quantum computer using Shor's Algorithm.
Shor's Algorithm has a “asymptotic” behaviour of O((log N)3). I won't try to explain the exact meaning of this statement, but it is quite possible that current encryption keys could be broken in sub-second time frames. Also, simply doubling the length of the key would have a barely noticeable effect on the time taken. The limiting factor is likely to be the number of qubits required since you need at least as many qubits as the key length.
D-Wave
You may have heard of D-Wave quantum computers.
These are currently the only commercially available quantum computers. D-Wave are building quantum computers containing 512 qubits, which in theory could be in a super position of 2512 states.
Despite having such a large number of qubits, there is little evidence that they have been solving problems any faster than conventional computers.
D-Wave computers are special purpose “quantum annealing” computers. The quantum computers that I have been describing so far are known as “quantum gate” computers. Describing the differences are beyond the scope of this (already long) article.
Before they can start out performing conventional computers, it is possible that D-Wave simply needs to use more qubits, or perhaps they may need to figure out how to make more effective use of their existing qubits. However, it quite possibly will not be long before we start seeing impressive results.
Some philosophy
Describing quantum computing in terms of superpositions of states that “collapse” to the observed state upon “measurement” is a very conventional approach to explaining the physics behind quantum computing. However, there are some serious deficiencies with this approach.
Probably the most fundamental problem is: What is so special about measurement that it causes quantum superpositions to collapse?
The measuring equipment itself is made of the same stuff as the qubits being measured (protons, neutrons, electrons, and photons).
When measuring a qubit that is in a superposition of two different states, there is nothing in quantum physics that says why the measuring equipment might cause the superposition to collapse to a single state instead of the measuring equipment becoming entangled with the qubit. Instead of the quantum state collapsing, the result could be a superposition of the following two states:
- the qubit being 0 and the measuring equipment detecting 0
- the qubit being 1 and the measuring equipment detecting 1
If you consider your conscious awareness to be nothing more than patterns of activity in your brain, and that your brain is governed by the laws of physics, then there is nothing in quantum physics that says why, when you look at the measurement outcome, you yourself does not become entangled with the quantum qubit and the measuring equipment. The result would be a superposition of the following two states:
- the qubit being 0, the measuring equipment detecting 0, and you being conscious of the measurement being 0
- the qubit being 1, the measuring equipment detecting 1, and you being conscious of the measurement being 1
Think of it as two alternative realities existing. In one reality you see a 0, and in the other you see a 1. Quantum interference is the only ways that these realities interact.
Variations on this interpretation of quantum physics are taken quite seriously by many physicists and physics philosophers, and is commonly referred to as the “Many Worlds” interpretation of quantum physics. Much has been written on the topic, and an internet search will point you to many good (and not so good) articles.
Quantum computing provides a nice way of looking at some of these issues. It may even provide a way of simulating ideas by, for example, representing different states of an observer using qubits.
This article has already covered more topics than I originally planned. However, I feel the need to include a little bit of a mathematical explanation to some of the material. For those that are not interested in the mathematics, feel free to skip to the Useful Links Section at the end.
Some mathematics
In this article I used little blue disks with red arrows to represent the probabilities of a set of bits or qubits being in different states. It is likely that I caused some confusion by quietly using the disks in subtly different ways when describing two quite different types of uncertainty.
When describing ordinary non-quantum bits, the system is in a definite state, but which state that is may be unknown. In this situation, it is most convenient if the arrow lengths are proportional to the probabilities of the respective states so that they can be added head to tail. If there were two scenarios, S1 and S2, both ending in the same state, where S1 has a probability of p1 and S2 has a probability of p2, then the probability of that final state is p1 + p2.
When describing qubits in a superposition of different states, it is no longer simply a case of not knowing which state they are in, the system actually seems to be in multiple states at once. In this situation, it is most convenient if the arrow lengths are proportional to the square roots of the probabilities of the respective states (the disk areas now effectively represent probabilities except for a factor of π). The arrow directions represent their phases. When two scenarios end in the same state, you need to use vector addition to add the arrows.
The arrows represent what physicists call “amplitudes”.
Conventionally, an amplitude is represented using a complex number whose value on the complex number plane coincides with the end of our arrow. If our arrow has a length r and a phase θ, then it is represented as the complex number:
r (cos(θ) + i sin(θ))
If a state had this amplitude, then the probability of that state being the outcome of a measurement is r2.
When we talk of “adding arrows head to tail”, we can simply add the corresponding complex numbers using ordinary complex number arithmetic.
Given that the probabilities of all possible outcomes have to add up to 1, it follows that the sum of the squares of the amplitude magnitudes also have to add up to 1. All quantum operators preserve this property.
If the amplitudes for the 0 and 1 states of a qubit are the (possibly complex) numbers a0 and a1 respectively, then applying a Hadamard results in the amplitudes of 0 and 1 becoming (1/√2)(a0 + a1) and (1/√2)(a0 - a1) respectively.
For the simple case of a qubit being 100% in the 1 state with a phase of 0, applying a Hadamard results in the amplitudes of 0 and 1 being 1/√2 and -1/√2 respectively. Notice that if you square and add these together that you get 1.
That is already more mathematics as I wanted to cover in this article. For more, see some of the useful links listed in the next section.
Useful links
- A excellent learning resource is John Watrous' Introduction to Quantum Computing Lecture Notes .
- Vazirani's online course: Quantum Mechanics and Quantum Computation is also excellent.
- If you want to experiment with the various qubit operators, then have a play with the Quantum Computer Gate Playground .
- Try doing some quantum programming using the jsqubits runner , or the Quantum Computing Playground


Netflex est une application web équivalante à une To-Do-List, qui permet de gérer les séries que l'on souhaite regarder. Celle-ci permet de créer une "WatchList" et d’obtenir des informations (nombre de saisons, nombre d’épisodes, acteurs...) sur les séries.
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
What things you need to install the software and how to install them
Give examples
A step by step series of examples that tell you how to get a development env running
Say what the step will be
Give the example
And repeat
until finished
End with an example of getting some data out of the system or using it for a little demo
Explain how to run the automated tests for this system
Explain what these tests test and why
Give an example
Explain what these tests test and why
Give an example
Add additional notes about how to deploy this on a live system
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
We use SemVer for versioning. For the versions available, see the tags on this repository.
This project is licensed under the MIT License - see the LICENSE.md file for details


Class ClientBuilderExtensions
Inheritance
System.Object
ClientBuilderExtensions
Namespace: Orleans
Assembly: Orleans.Core.Legacy.dll
Syntax
public static class ClientBuilderExtensions : object
Methods
| Improve this Doc View SourceConfiguration(IClusterClient)
Gets the client configuration.
Declaration
public static ClientConfiguration Configuration(this IClusterClient client)
Parameters
| Type | Name | Description |
|---|---|---|
| IClusterClient | client |
Returns
| Type | Description |
|---|---|
| ClientConfiguration |
LoadConfiguration(IClientBuilder)
Loads configuration from the standard client configuration locations.
Declaration
public static IClientBuilder LoadConfiguration(this IClientBuilder builder)
Parameters
| Type | Name | Description |
|---|---|---|
| IClientBuilder | builder | The builder. |
Returns
| Type | Description |
|---|---|
| IClientBuilder | The builder. |
Remarks
This method loads the first client configuration file it finds, searching predefined directories for predefined file names. The following file names are tried in order:
LoadConfiguration(IClientBuilder, FileInfo)
Loads configuration from the provided location.
Declaration
public static IClientBuilder LoadConfiguration(this IClientBuilder builder, FileInfo configurationFile)
Parameters
| Type | Name | Description |
|---|---|---|
| IClientBuilder | builder | The builder. |
| FileInfo | configurationFile |
Returns
| Type | Description |
|---|---|
| IClientBuilder | The builder. |
LoadConfiguration(IClientBuilder, String)
Loads configuration from the provided location.
Declaration
public static IClientBuilder LoadConfiguration(this IClientBuilder builder, string configurationFilePath)
Parameters
| Type | Name | Description |
|---|---|---|
| IClientBuilder | builder | The builder. |
| System.String | configurationFilePath |
Returns
| Type | Description |
|---|---|
| IClientBuilder | The builder. |
UseConfiguration(IClientBuilder, ClientConfiguration)
Specified the configuration to use for this client.
Declaration
public static IClientBuilder UseConfiguration(this IClientBuilder builder, ClientConfiguration configuration)
Parameters
| Type | Name | Description |
|---|---|---|
| IClientBuilder | builder | The client builder. |
| ClientConfiguration | configuration | The configuration. |
Returns
| Type | Description |
|---|---|
| IClientBuilder | The builder. |
Remarks
This method may only be called once per builder instance.


Bookshelf
Below is a list of some of my favorite reads, this is not a comprehensive list nor is it static. You will also find what I’m currently enjoying.
Currently reading
I am currently reading Finding The Mother Tree by Dr. Suzanne Simard. This fantastic memoir was written by UBC Professor Dr. Suzanne Simard on her journey uncovering some fantastical truths about our forests.
Books I have enjoyed
Braiding Sweetgrass by Robin Wall Kimmerer
It was through reading and discovering Dr. Kimmerer’s work that I felt my concerns about science and its methods be explained to me in a language of permission. As a budding biologist, reading this incredible work opened my eyes to a criticism of scientific thought I had failed to put into words.
Americanah by Chimamanda Ngozi Adichie
I first read this book when I immigrated to Canada to start University. The story of Ifemelu (the protagonist), helped me ease the difficulties and challenges of transitioning to the North American way of life. Having lived abroad before I thought I knew what to expect but the cultural shock of moving from Brazil to Costa Rica did not prepare me for the winter in Vancouver.
The Overstory by Richard Powers
A recent read that is on this list because of its fantastic prose but also powerful storytelling as a call to action. A lot of the books I read are about nature and this is one of my favorite nature books because it’s about people.
Green Phoenix: Restoring the Tropical Forests of Guanacaste, Costa Ricaby William Allen
A telling of the decades long effort to change the course of an ecosystem set for extinction, this book showed me that sometimes, good does actually triumph. With the ever-present climate anxiety we experience, this book gave me the inspiration to continue pursuing what may seem like unattainable goals.
Uncanny Valleyby Anna Wiener
A gripping memoir that offers insight into the culture of capitalistic innovation plaguing the technology sector. Instead of being grimm and apocalyptic, Wiener brings a sardonic yet touching lens of humans at work. Her experience is unique and although may not be the norm, helps illustrate how “productivity culture” has shaped our modern experience of work.
Got any reading recommendations? Send them my way via email!


Hi it's runhead. Here's a shop:
Style
Grey T-shirt
Grey vest
Grey long sleeve tshirt
Fluoro long sleeve tshirt
Gender
Male
Female
Size
XS
S
M
L
XL
Pay


Lions
Home
The Mighty Tiger
'Panthera tigris'
Tiger Facts
The tiger is the biggest species of the cat family.
Around half of tiger cubs don’t live beyond two years of age.
Tiger cubs leave their mother when they are around 2 years of age.
A group of tigers is known as an ‘ambush’ or ‘streak’.


Field of Study : Computing
Qualification : 2:1 Bachelor Degree with Hinours
Graduation Date : 2004
Field of Study : Computer Studies
Qualification : Higher National Diploma
Graduation Date : 2002
Field of Study : Computer Studies
Qualification : National BTEC Diploma
Graduation Date : 2000


You can download the source code from here: https://github.com/erseco/ejercicios_sql
All of you know Microsoft SQL Server, but is not the only database engine that exists.
¿Can you remember the name of any other SQL engine?
For this practice we are going to use AlaSQL (http://alasql.org/) a lightweight client-side in-memory SQL database designed to work directly in the browser.
After finishing, please fill this quiz about this class (it is in Spanish, I promise)


Last updated December 29, 2018
The information provided by Ocean Ink LLC (“we,” “us” or “our”) on https://www.oceanink.net (the “Site”) is for general informational purposes only. All information on the Site is provided in good faith, however we make no
representation or warranty of any kind, express or implied, regarding the
accuracy, adequacy, validity, reliability, availability or completeness of any
information on the Site. UNDER NO CIRCUMSTANCE SHALL WE HAVE ANY LIABILITY TO YOU FOR ANY LOSS OR DAMAGE OF ANY KIND INCURRED AS A RESULT OF THE USE OF THE SITE OR RELIANCE ON ANY
INFORMATION PROVIDED ON THE SITE.
EXTERNAL LINKS
DISCLAIMER
The Site may contain (or you may be sent through the Site ) links to other
websites or content belonging to or originating from third parties or links to
websites and features in banners or other advertising. Such external links are
not investigated, monitored, or checked for accuracy, adequacy, validity, reliability,
availability or completeness by us. WE DO NOT WARRANT, ENDORSE, GUARANTEE, OR
ASSUME RESPONSIBILITY FOR THE ACCURACY OR RELIABILITY OF ANY INFORMATION
OFFERED BY THIRD-PARTY WEBSITES LINKED THROUGH THE SITE OR ANY WEBSITE OR
FEATURE LINKED IN ANY BANNER OR OTHER ADVERTISING. WE WILL NOT BE A PARTY TO OR
IN ANY WAY BE RESPONSIBLE FOR MONITORING ANY TRANSACTION BETWEEN YOU AND THIRD-PARTY PROVIDERS OF PRODUCTS OR SERVICES.
PROFESSIONAL DISCLAIMER
The Site cannot and does not contain medical/health advice. The medical/health information is provided for general informational and educational purposes only and is not a substitute for professional advice. Accordingly, before taking any actions based upon such information, we encourage you to consult with the appropriate professionals. We do not provide any kind of medical/health advice.
TESTIMONIALS DISCLAIMER
The Site may contain testimonials by users of our products and/or services. These testimonials reflect the real-life experiences and opinions of such users. However, the experiences are personal to those particular users, and may not necessarily be representative of all users of our products and/or services. We do not claim, and you should not assume, that all users will have the same experiences. YOUR INDIVIDUAL RESULTS MAY VARY.
The testimonials on the Site are submitted in various forms such as text, audio and/or video, and are reviewed by us before being posted. They appear on the Site verbatim as given by the users, except for the correction of grammar or typing errors. Some testimonials may have been shortened for the sake of brevity where the full testimonial contained extraneous information not relevant to the general public.
The views and opinions contained in the testimonials belong solely to the individual user and do not reflect our views and opinions. We are not affiliated with users who provide testimonials, and users are not paid or otherwise compensated for their testimonials.
The testimonials on the Site are not intended, nor should
they be construed, as claims that our products and/or services can be used to
diagnose, treat, mitigate, cure, prevent or otherwise be used for any disease
or medical condition. No testimonials have been clinically proven or evaluated.


On 26 May 2017, 6 new articles were published in 6 journals.
Pick Your Poison: Choice of Activity Determines Mood Management Following A Stressful Task
The New Disciplinology: Research, Theory, and Remaining Puzzles on the School-to-Prison Pipeline
Self-Reported Impulsivity and Its Relation to Executive Functions in Interned Youth
The Victim–offender Relationship and Police Charging Decisions For Juvenile Delinquents


--- layout: post title: LESS Is More - Using Twitter's Bootstrap In The Rails 3.1 Asset Pipeline categories: - ruby-rails - javascript ---
This weekend I decided to experiment with LESS CSS by replacing the existing Sass and Compass code that had been built thus far a small project. Why? Three basic reasons. First, I wanted to see how LESS stacked up. Second, I was intrigued by some of LESS' features, in particular their namespace support. Lastly, I wanted to use Twitter's Bootstrap project as a baseline for my design. Since Rails 3.1 has been out for some time, I was expecting the move to LESS to go considerably smoother than my pre-release attempts with Compass and Sass. I was wrong.
So the tilt gem already supported LESS templates and that means that Sprockets and the asset pipeline rendering technically did too. But there was no official less-rails gem that setup a standard configuration for other gems to hook into. This meant that libraries that distributed the Twitter Bootstrap assets were often hard to use or had inconsistent results. For example, it was not possible to load the Bootstrap's assets in such as way that let you build on top of the LESS mixins they had build. Nor were those assets namespaced in such a way that would allow you to have a modal.less
asset as it would have conflicted with Bootstrap's version. So since I apparently have a bunch of free time and I hate building on top of a bad foundation, I set out to learn both Rails::Railtie
and Rails::Engine
to build the proper tools for LESS and Bootstrap in the Rails 3.1 asset pipeline.
I introduce you to both the new less-rails and less-rails-bootstrap gems. Take a look at the source code if you ever wanted to learn how to implement a simple Rails::Railtie or Engine. But assuming you want to use Twitter's Bootstrap, here are a few examples to get you started. First just bundle up to less-rails-bootstrap, it will automatically pull in less-rails and less.rb via their dependencies. BTW, I am going to keep the semantic versioning of the less-rails-bootstrap gem in sync with the major and minor versions of the Bootstrap project.
{% highlight ruby %} gem 'less-rails-bootstrap', '~> 1.3.0' {% endhighlight %}
From here, the easiest way to use Bootstrap is to require it in your application.css
file. Doing so will compile the complete LESS libraries files for Bootstrap. Note how we namespace the files using a simple directory structure.
Alternatively, in a file with the .css.less
extension, you can import the entire Bootstrap LESS framework. This will allow you to use Bootstrap's variables and mixins in your CSS that follows. Remember, unlike other CSS frameworks, requiring or importing Bootstrap will include all the CSS for building a bootstrapped website. If you only want variables or mixins, you will have to import those discreet files, see next section.
Maybe all you want to use are the variables and mixins that come with Twitter Bootstrap. No problem, just import them individually from you own .css.less
file. In this case only the #foo
selector is output.
Using the Bootstrap JavaScript files is just as easy. Again, you can include all them with a single directive from your application.js
file. Optionally, you can require only the files you need like require twitter/bootstrap/modal
.
The less-rails project has already started getting some good feedback. Soon we hope to implement all the features that you may have used in the sass-rails project, like asset pipeline helpers. One last thing, I wanted to say thanks to Nicolas Mérouze for opening up the old less-rails gem space on rubygems.org for the new gem!


Cameron Forrest
About
Portfolio
Contact
Portfolio
Hangman
RPG Game
Trivia Game
Vandy Info Widget
Rock Paper Scissors


Devlytics
Devlytics was a Team Productivity and Analytics Tool
Active for over 2 years, provided metrics and a clear picture on the performance of the team as well as problematic areas in the codebase
Here are some of the public accounts we had on the system:
Rails Framework
Dev.to
Laravel Framework
Sidekiq
Amber Framework
Ember.js
Redash
VSCode
MobX
Crystal Programming Language


R is an excellent tool for creating graphs and plots. The graphic capabilities and functions provided by the base R installation is called the base R graphics. Numerous packages exist to extend the functionality of base graphics.
We can try out plotting a few of the common plot types. Let’s start with a scatterplot. First we create a data.frame
as this is the most commonly used data object.
Now we have a dataframe with two continuous variables that can be plotted against each other.
This is probably the simplest and most basic plots. We can modify the x and y axis labels.
We can change the point to a line.
Let’s add a categorical column to our dataframe.
And then colour the points by category.
# subset data
dfr_c1 <- subset(dfr,dfr$cat == "C1")
dfr_c2 <- subset(dfr,dfr$cat == "C2")
plot(dfr_c1$a,dfr_c1$b,xlab="Variable a",ylab="Variable b",col="red",pch=1)
points(dfr_c2$a,dfr_c2$b,col="blue",pch=2)
legend(x="topright",legend=c("C1","C2"),
col=c("red","blue"),pch=c(1,2))
plot
Let’s create a barplot.
Grid graphics have a completely different underlying framework compared to base graphics. Generally, base graphics and grid graphics cannot be plotted together. The most popular grid-graphics based plotting library is ggplot2.
Let’s create the same plot as before using ggplot2. Make sure you have the package installed.
library(ggplot2)
ggplot(dfr)+
geom_point(mapping = aes(x=a,y=b,colour=cat))+
labs(x="Variable a",y="Variable b")
plot
It is generally easier and more consistent to create plots using the ggplot2 package compared to the base graphics.
Let’s create a barplot as well.
Let’s take a look at saving plots.
Note This part is just to give you a quick look into how you can save images from Rstudio quickly. The different format of images will be explained in a lecture tomorrow.
The general idea for saving plots is open a graphics device, create the plot and then close the device. We will use png here. Check out ?png
for the arguments and other devices.
The same idea can be applied to ggplot2, but in a slightly different way. First save the file to a variable, and then export the plot.
Tip ggplot2 also has another easier helper function to export images.
Make sure the library is loaded in your environment.
In the previous section we saw very quickly how to use ggplot
. Let’s take a look at it again a bit more carefully. For this let’s first look into a simple data that is available in R. We use the iris
data for this to start with.
This dataset has four continuous variables and one categorical variable. It is important to remember about the data type when plotting graphs
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
When we initiate the ggplot object using the data, it just creates a blank plot!
Now we can specify what we want on the x and y axes using aesthetic mapping. And we specify the geometric using geoms
. Note that the variable names do not have double quotes ""
like in base plots.
Further geoms can be added. For example let’s add a regression line. When multiple geoms with the same aesthetics are used, they can be specified as a common mapping. Note that the order in which geoms are plotted depends on the order in which the geoms are supplied in the code. In the code below, the points are plotted first and then the regression line.
plot
There are many other geoms
and you can find most of them here in this cheatsheet
Let’s also try to use ggplot
for a “more common” gene counts dataset. Let’s use the merged_data_long
or the gc_long
object we created in the earlier session.
Note You can notice that the ggplot sorts the factors
or vaiables
alpha-numerically, like in the case above with Sample_Name
.
Tip There is a trick that you can use to give the order of variables manually. The example is shown below:
First, if we look at the iris
data, we can use the categorical column Species
to color the points. The color aesthetic is used by geom_point and geom_smooth. Three different regression lines are now drawn. Notice that a legend is automatically created
ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width,color=Species))+
geom_point()+
geom_smooth(method="lm")
plot
If we wanted to keep a common regression line while keeping the colors for the points, we could specify color aesthetic only for geom_point
.
Similarly, we can do the same with the gene counts data.
ggplot(data = gc_long) +
geom_boxplot(mapping = aes(x = Sample_Name, y = log10(count + 1), color = Time))
plot
Tip We can also use the fill
aesthetic to give it a better look.
We can change the default colors by specifying new values inside a scale.
ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
geom_point(aes(color=Species))+
geom_smooth(method="lm")+
scale_color_manual(values=c("red","blue","green"))
plot
Tip To specify manual colors, you could specify by their names
or their hexadecimal codes
. For example, you can choose the colors based on names
from an online source like in this cheatsheet or you can use the hexadecimal code
and choose it from a source like here. I personally prefer the hexa
based options for manual colors.
We can also map the colors to a continuous variable. This creates a color bar legend item.
ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
geom_point(aes(color=Sepal.Width))+
geom_smooth(method="lm")
plot
Tip Here, you can also choose different palettes
for choosing the right continuous pallet. There are some common packages of palettes that are used very often. RColorBrewer and wesanderson, if you are fan of his choice of colors ;)
library(wesanderson)
ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
geom_point(aes(color=Sepal.Width))+
geom_smooth(method="lm") +
scale_color_gradientn(colours = wes_palette("Moonrise3"))
plot
Tip You can also use simple R base color palettes like rainbow()
or terrain.colors()
. Use ?
and look at these functions to see, how to use them.
We can change the size of all points by a fixed amount by specifying size outside the aesthetic parameter.
We can map another variable as size of the points. This is done by specifying size inside the aesthetic mapping. Now the size of the points denote Sepal.Width
. A new legend group is created to show this new aesthetic.
Here, as a quick example, we will try to make use of the different combinations of geoms
, aes
and color
in simple plots.
Let’s take a quick look at some of widely used functions like histograms and density plots in ggplot
. Intuitively, these can be drawn with geom_histogram()
and geom_density()
. Using bins
and binwidth
in geom_histogram()
, one can customize the histogram.
Let’s look at the sample plot in density.
The above plot is not very informative, let’s see how the different species contribute:
plot
Note The alpha
option inside geom_density
controls the transparency of the plot.
Task Make boxplots
similar to the one we did here in this exercise for the other three counts (counts_filtered.txt
, counts_vst.txt
and counts_deseq2.txt
).
Tip You can save the plots themselves as R objects. You will get the plot by just calling those objects. You can then add layers to those objects. An example is shown below:
plot_obj_1 <- ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
geom_point(aes(color=Sepal.Width))+
geom_smooth(method="lm")
plot_obj_1
plot
plot
This way, you can create different plot objects for the different counts, we will use them in the later exercises.
## R version 3.6.3 (2020-02-29)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.1 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] wesanderson_0.3.6 forcats_0.5.0 stringr_1.4.0 purrr_0.3.4
## [5] readr_1.3.1 tidyr_1.1.2 tibble_3.0.4 tidyverse_1.3.0
## [9] reshape2_1.4.4 ggplot2_3.3.2 dplyr_1.0.2 captioner_2.2.3
## [13] bookdown_0.20 knitr_1.29
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.1.0 xfun_0.18 splines_3.6.3 haven_2.3.1
## [5] lattice_0.20-40 colorspace_1.4-1 vctrs_0.3.4 generics_0.0.2
## [9] htmltools_0.5.0 yaml_2.2.1 mgcv_1.8-31 blob_1.2.1
## [13] rlang_0.4.8 pillar_1.4.6 glue_1.4.2 withr_2.3.0
## [17] DBI_1.1.0 dbplyr_1.4.4 modelr_0.1.8 readxl_1.3.1
## [21] lifecycle_0.2.0 plyr_1.8.6 munsell_0.5.0 gtable_0.3.0
## [25] cellranger_1.1.0 rvest_0.3.6 evaluate_0.14 labeling_0.4.2
## [29] fansi_0.4.1 broom_0.7.0 Rcpp_1.0.5 scales_1.1.1
## [33] backports_1.1.10 jsonlite_1.7.1 fs_1.5.0 farver_2.0.3
## [37] hms_0.5.3 digest_0.6.27 stringi_1.5.3 grid_3.6.3
## [41] cli_2.1.0 tools_3.6.3 magrittr_1.5 crayon_1.3.4
## [45] pkgconfig_2.0.3 ellipsis_0.3.1 Matrix_1.2-18 xml2_1.3.2
## [49] reprex_0.3.0 lubridate_1.7.9 rstudioapi_0.11 assertthat_0.2.1
## [53] rmarkdown_2.3 httr_1.4.2 R6_2.5.0 nlme_3.1-144
## [57] compiler_3.6.3
End of document