diff --git a/README.md b/README.md index 261784af..e5075916 100644 --- a/README.md +++ b/README.md @@ -33,31 +33,59 @@ Beginning with Tensorflow 2, I started to use Google Colab. For those courses, u VIP Course Links =================== -*** Note: if any of these coupons becomes out of date, check my website (https://lazyprogrammer.me) for the latest version. I will probably just keep incrementing them numerically, e.g. FINANCEVIP2, FINANCEVIP3, etc.. +**Advanced AI: Deep Reinforcement Learning in PyTorch (v2)** + +https://deeplearningcourses.com/c/deep-reinforcement-learning-in-pytorch + + +**Data Science: Transformers for Natural Language Processing** + +https://deeplearningcourses.com/c/data-science-transformers-nlp + + +**Machine Learning: Natural Language Processing in Python (V2)** + +https://deeplearningcourses.com/c/natural-language-processing-in-python + **Time Series Analysis, Forecasting, and Machine Learning** -https://www.udemy.com/course/time-series-analysis/?couponCode=TIMEVIP4 +https://deeplearningcourses.com/c/time-series-analysis **Financial Engineering and Artificial Intelligence in Python** -https://www.udemy.com/course/ai-finance/?couponCode=FINANCEVIP13 +https://deeplearningcourses.com/c/ai-finance **PyTorch: Deep Learning and Artificial Intelligence** -https://www.udemy.com/course/pytorch-deep-learning/?couponCode=PYTORCHVIP18 +https://deeplearningcourses.com/c/pytorch-deep-learning **Tensorflow 2.0: Deep Learning and Artificial Intelligence** (VIP Version) + https://deeplearningcourses.com/c/deep-learning-tensorflow-2 +**Math 0-1: Linear Algebra for Data Science & Machine Learning** + +https://deeplearningcourses.com/c/linear-algebra-data-science + +**Math 0-1: Probability for Data Science & Machine Learning** + +https://deeplearningcourses.com/c/probability-data-science-machine-learning + Deep Learning Courses Exclusives ================================ +Data Science: Bayesian Linear Regression in Python +https://deeplearningcourses.com/c/bayesian-linear-regression-in-python + +Data Science: Bayesian Classification in Python +https://deeplearningcourses.com/c/bayesian-classification-in-python + Classical Statistical Inference and A/B Testing in Python https://deeplearningcourses.com/c/statistical-inference-in-python @@ -72,8 +100,26 @@ https://deeplearningcourses.com/c/matlab Other Course Links ================== -Tensorflow 2.0: Deep Learning and Artificial Intelligence (non-VIP version) -https://www.udemy.com/course/deep-learning-tensorflow-2/?referralCode=E10B72D3848AB70FE1B8 +Generative AI: ChatGPT & OpenAI LLMs in Python +https://deeplearningcourses.com/c/genai-openai-chatgpt + +Math 0-1: Matrix Calculus for Data Science & Machine Learning +https://deeplearningcourses.com/c/matrix-calculus-machine-learning + +Machine Learning: Modern Computer Vision & Generative AI +https://deeplearningcourses.com/c/computer-vision-kerascv + +DeepFakes & Voice Cloning: Machine Learning The Easy Way +https://deeplearningcourses.com/c/deepfakes-voice-cloning + +Financial Analysis: Build a ChatGPT Pairs Trading Bot +https://deeplearningcourses.com/c/chatgpt-pairs-trading + +Math 0-1: Calculus for Data Science & Machine Learning +https://deeplearningcourses.com/c/calculus-data-science + +Data Science & Machine Learning: Naive Bayes in Python +https://deeplearningcourses.com/c/data-science-machine-learning-naive-bayes-in-python Cutting-Edge AI: Deep Reinforcement Learning in Python https://deeplearningcourses.com/c/cutting-edge-artificial-intelligence @@ -117,7 +163,7 @@ https://deeplearningcourses.com/c/data-science-linear-regression-in-python Deep Learning Prerequisites: Logistic Regression in Python https://deeplearningcourses.com/c/data-science-logistic-regression-in-python -Deep Learning in Python +Data Science: Deep Learning and Neural Networks in Python https://deeplearningcourses.com/c/data-science-deep-learning-in-python Cluster Analysis and Unsupervised Machine Learning in Python @@ -129,10 +175,10 @@ https://deeplearningcourses.com/c/data-science-supervised-machine-learning-in-py Bayesian Machine Learning in Python: A/B Testing https://deeplearningcourses.com/c/bayesian-machine-learning-in-python-ab-testing -Easy Natural Language Processing in Python +Data Science: Natural Language Processing in Python https://deeplearningcourses.com/c/data-science-natural-language-processing-in-python -Practical Deep Learning in Theano and TensorFlow +Modern Deep Learning in Python https://deeplearningcourses.com/c/data-science-deep-learning-in-theano-tensorflow Ensemble Machine Learning in Python: Random Forest and AdaBoost diff --git a/ann_logistic_extra/ann_train.py b/ann_logistic_extra/ann_train.py index 5c84a7e4..15710e76 100644 --- a/ann_logistic_extra/ann_train.py +++ b/ann_logistic_extra/ann_train.py @@ -48,8 +48,8 @@ def predict(P_Y_given_X): def classification_rate(Y, P): return np.mean(Y == P) -def cross_entropy(T, pY): - return -np.mean(T*np.log(pY)) +def cross_entropy(Y, pY): + return -np.sum(Y * np.log(pY)) / len(T) # train loop @@ -66,18 +66,22 @@ def cross_entropy(T, pY): test_costs.append(ctest) # gradient descent - W2 -= learning_rate*Ztrain.T.dot(pYtrain - Ytrain_ind) - b2 -= learning_rate*(pYtrain - Ytrain_ind).sum(axis=0) - dZ = (pYtrain - Ytrain_ind).dot(W2.T) * (1 - Ztrain*Ztrain) - W1 -= learning_rate*Xtrain.T.dot(dZ) - b1 -= learning_rate*dZ.sum(axis=0) + gW2 = Ztrain.T.dot(pYtrain - Ytrain_ind) + gb2 = (pYtrain - Ytrain_ind).sum(axis=0) + dZ = (pYtrain - Ytrain_ind).dot(W2.T) * (1 - Ztrain * Ztrain) + gW1 = Xtrain.T.dot(dZ) + gb1 = dZ.sum(axis=0) + W2 -= learning_rate * gW2 + b2 -= learning_rate * gb2 + W1 -= learning_rate * gW1 + b1 -= learning_rate * gb1 if i % 1000 == 0: print(i, ctrain, ctest) print("Final train classification_rate:", classification_rate(Ytrain, predict(pYtrain))) print("Final test classification_rate:", classification_rate(Ytest, predict(pYtest))) -legend1, = plt.plot(train_costs, label='train cost') -legend2, = plt.plot(test_costs, label='test cost') -plt.legend([legend1, legend2]) +plt.plot(train_costs, label='train cost') +plt.plot(test_costs, label='test cost') +plt.legend() plt.show() \ No newline at end of file diff --git a/ann_logistic_extra/logistic_softmax_train.py b/ann_logistic_extra/logistic_softmax_train.py index 2bdc114f..94874f14 100644 --- a/ann_logistic_extra/logistic_softmax_train.py +++ b/ann_logistic_extra/logistic_softmax_train.py @@ -44,8 +44,8 @@ def predict(P_Y_given_X): def classification_rate(Y, P): return np.mean(Y == P) -def cross_entropy(T, pY): - return -np.mean(T*np.log(pY)) +def cross_entropy(Y, pY): + return -np.sum(Y * np.log(pY)) / len(Y) # train loop @@ -70,7 +70,7 @@ def cross_entropy(T, pY): print("Final train classification_rate:", classification_rate(Ytrain, predict(pYtrain))) print("Final test classification_rate:", classification_rate(Ytest, predict(pYtest))) -legend1, = plt.plot(train_costs, label='train cost') -legend2, = plt.plot(test_costs, label='test cost') -plt.legend([legend1, legend2]) +plt.plot(train_costs, label='train cost') +plt.plot(test_costs, label='test cost') +plt.legend() plt.show() \ No newline at end of file diff --git a/ann_logistic_extra/logistic_train.py b/ann_logistic_extra/logistic_train.py index c9a22815..abedd5ba 100644 --- a/ann_logistic_extra/logistic_train.py +++ b/ann_logistic_extra/logistic_train.py @@ -55,9 +55,9 @@ def cross_entropy(T, pY): print("Final train classification_rate:", classification_rate(Ytrain, np.round(pYtrain))) print("Final test classification_rate:", classification_rate(Ytest, np.round(pYtest))) -legend1, = plt.plot(train_costs, label='train cost') -legend2, = plt.plot(test_costs, label='test cost') -plt.legend([legend1, legend2]) +plt.plot(train_costs, label='train cost') +plt.plot(test_costs, label='test cost') +plt.legend() plt.show() diff --git a/ann_logistic_extra/process.py b/ann_logistic_extra/process.py index 785755b7..0048f9e0 100644 --- a/ann_logistic_extra/process.py +++ b/ann_logistic_extra/process.py @@ -21,7 +21,7 @@ def get_data(): # df.head() # easier to work with numpy array - data = df.values + data = df.to_numpy() # shuffle it np.random.shuffle(data) diff --git a/calculus/WHERE ARE THE NOTEBOOKS.txt b/calculus/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/calculus/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/calculus/extra_reading.txt b/calculus/extra_reading.txt new file mode 100644 index 00000000..404cc6d0 --- /dev/null +++ b/calculus/extra_reading.txt @@ -0,0 +1,2 @@ +Calculus: Early Transcendentals +https://amzn.to/3Kwmabe \ No newline at end of file diff --git a/chatgpt_trading/WHERE ARE THE NOTEBOOKS.txt b/chatgpt_trading/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/chatgpt_trading/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/chatgpt_trading/extra_reading.txt b/chatgpt_trading/extra_reading.txt new file mode 100644 index 00000000..59a5da5d --- /dev/null +++ b/chatgpt_trading/extra_reading.txt @@ -0,0 +1,5 @@ +ARIMA (for mean reversion) +https://deeplearningcourses.com/c/time-series-analysis + +Financial Engineering +https://deeplearningcourses.com/c/ai-finance \ No newline at end of file diff --git a/cnn_class/WHERE ARE THE NOTEBOOKS.txt b/cnn_class/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/cnn_class/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/cnn_class/exercises.txt b/cnn_class/exercises.txt index 4fdbc856..81a2e5a4 100644 --- a/cnn_class/exercises.txt +++ b/cnn_class/exercises.txt @@ -13,7 +13,7 @@ https://lazyprogrammer.me/course_files/exercises/ecoli.csv CNN https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge -https://lazyprogrammer.me/course_files/fer2013.csv +https://archive.org/download/fer2013_202311/fer2013.csv NLP https://www.kaggle.com/crowdflower/twitter-airline-sentiment diff --git a/cnn_class/extra_reading.txt b/cnn_class/extra_reading.txt index c7cc13b8..ed16dc09 100644 --- a/cnn_class/extra_reading.txt +++ b/cnn_class/extra_reading.txt @@ -5,7 +5,7 @@ ImageNet Classification with Deep Convolutional Neural Networks https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf Convolution arithmetic tutorial -http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html +https://theano-pymc.readthedocs.io/en/latest/tutorial/conv_arithmetic.html Very Deep Convolutional Networks for Large-Scale Visual Recognition http://www.robots.ox.ac.uk/~vgg/research/very_deep/ diff --git a/cnn_class2/WHERE ARE THE NOTEBOOKS.txt b/cnn_class2/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/cnn_class2/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/cnn_class2/extra_reading.txt b/cnn_class2/extra_reading.txt index d68f40bb..593bc0cc 100644 --- a/cnn_class2/extra_reading.txt +++ b/cnn_class2/extra_reading.txt @@ -11,4 +11,10 @@ Deep Residual Learning for Image Recognition https://arxiv.org/abs/1512.03385 Going Deeper with Convolutions (Inception) -https://arxiv.org/abs/1409.4842 \ No newline at end of file +https://arxiv.org/abs/1409.4842 + +Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift +https://arxiv.org/abs/1502.03167 + +Deep learning improved by biological activation functions +https://arxiv.org/pdf/1804.11237.pdf \ No newline at end of file diff --git a/cnn_class2/siamese.py b/cnn_class2/siamese.py index a8e5894f..4c43f163 100644 --- a/cnn_class2/siamese.py +++ b/cnn_class2/siamese.py @@ -425,7 +425,7 @@ def get_test_accuracy(threshold=0.85): valid_steps = int(np.ceil(len(test_positives) * 2 / batch_size)) # fit the model -r = model.fit_generator( +r = model.fit( train_generator(), steps_per_epoch=train_steps, epochs=20, diff --git a/cnn_class2/use_pretrained_weights_resnet.py b/cnn_class2/use_pretrained_weights_resnet.py index 39bed211..8f3aae71 100644 --- a/cnn_class2/use_pretrained_weights_resnet.py +++ b/cnn_class2/use_pretrained_weights_resnet.py @@ -8,7 +8,7 @@ from keras.layers import Input, Lambda, Dense, Flatten from keras.models import Model -from keras.applications.resnet50 import ResNet50, preprocess_input +from keras.applications.resnet import ResNet50, preprocess_input # from keras.applications.inception_v3 import InceptionV3, preprocess_input from keras.preprocessing import image from keras.preprocessing.image import ImageDataGenerator @@ -21,21 +21,21 @@ # re-size all the images to this -IMAGE_SIZE = [224, 224] # feel free to change depending on dataset +IMAGE_SIZE = [100, 100] # feel free to change depending on dataset # training config: epochs = 16 batch_size = 32 # https://www.kaggle.com/paultimothymooney/blood-cells -train_path = '../large_files/blood_cell_images/TRAIN' -valid_path = '../large_files/blood_cell_images/TEST' +# train_path = '../large_files/blood_cell_images/TRAIN' +# valid_path = '../large_files/blood_cell_images/TEST' # https://www.kaggle.com/moltean/fruits # train_path = '../large_files/fruits-360/Training' # valid_path = '../large_files/fruits-360/Validation' -# train_path = '../large_files/fruits-360-small/Training' -# valid_path = '../large_files/fruits-360-small/Validation' +train_path = '../large_files/fruits-360-small/Training' +valid_path = '../large_files/fruits-360-small/Validation' # useful for getting number of files image_files = glob(train_path + '/*/*.jp*g') @@ -125,7 +125,7 @@ # fit the model -r = model.fit_generator( +r = model.fit( train_generator, validation_data=valid_generator, epochs=epochs, diff --git a/cnn_class2/use_pretrained_weights_vgg.py b/cnn_class2/use_pretrained_weights_vgg.py index 542bcb48..849dd9f6 100644 --- a/cnn_class2/use_pretrained_weights_vgg.py +++ b/cnn_class2/use_pretrained_weights_vgg.py @@ -123,7 +123,7 @@ # fit the model -r = model.fit_generator( +r = model.fit( train_generator, validation_data=valid_generator, epochs=epochs, diff --git a/financial_engineering/go_here_instead.txt b/financial_engineering/go_here_instead.txt new file mode 100644 index 00000000..614b0afd --- /dev/null +++ b/financial_engineering/go_here_instead.txt @@ -0,0 +1 @@ +https://github.com/lazyprogrammer/financial_engineering diff --git a/hmm_class/sites.py b/hmm_class/sites.py index 617863f5..0187e03a 100644 --- a/hmm_class/sites.py +++ b/hmm_class/sites.py @@ -2,6 +2,8 @@ # https://udemy.com/unsupervised-machine-learning-hidden-markov-models-in-python # http://lazyprogrammer.me # Create a Markov model for site data. +from __future__ import print_function, division +from future.utils import iteritems import numpy as np transitions = {} @@ -14,19 +16,19 @@ row_sums[s] = row_sums.get(s, 0.) + 1 # normalize -for k, v in transitions.iteritems(): +for k, v in iteritems(transitions): s, e = k transitions[k] = v / row_sums[s] # initial state distribution -print "initial state distribution:" -for k, v in transitions.iteritems(): +print("initial state distribution:") +for k, v in iteritems(transitions): s, e = k if s == '-1': - print e, v + print(e, v) # which page has the highest bounce? -for k, v in transitions.iteritems(): +for k, v in iteritems(transitions): s, e = k if e == 'B': - print "bounce rate for %s: %s" % (s, v) + print("bounce rate for %s: %s" % (s, v)) diff --git a/kerascv/extra_reading.txt b/kerascv/extra_reading.txt new file mode 100644 index 00000000..57ebec98 --- /dev/null +++ b/kerascv/extra_reading.txt @@ -0,0 +1,8 @@ +KerasCV List of Models +https://keras.io/api/keras_cv/models/ + +Fast R-CNN (Ross Girshick) +https://arxiv.org/pdf/1504.08083.pdf + +Focal Loss for Dense Object Detection (Lin et al.) +https://arxiv.org/abs/1708.02002 \ No newline at end of file diff --git a/kerascv/imagenet_label_names.json b/kerascv/imagenet_label_names.json new file mode 100644 index 00000000..37eeb166 --- /dev/null +++ b/kerascv/imagenet_label_names.json @@ -0,0 +1,1000 @@ +["tench", +"goldfish", +"great white shark", +"tiger shark", +"hammerhead shark", +"electric ray", +"stingray", +"cock", +"hen", +"ostrich", +"brambling", +"goldfinch", +"house finch", +"junco", +"indigo bunting", +"American robin", +"bulbul", +"jay", +"magpie", +"chickadee", +"American dipper", +"kite", +"bald eagle", +"vulture", +"great grey owl", +"fire salamander", +"smooth newt", +"newt", +"spotted salamander", +"axolotl", +"American bullfrog", +"tree frog", +"tailed frog", +"loggerhead sea turtle", +"leatherback sea turtle", +"mud turtle", +"terrapin", +"box turtle", +"banded gecko", +"green iguana", +"Carolina anole", +"desert grassland whiptail lizard", +"agama", +"frilled-necked lizard", +"alligator lizard", +"Gila monster", +"European green lizard", +"chameleon", +"Komodo dragon", +"Nile crocodile", +"American alligator", +"triceratops", +"worm snake", +"ring-necked snake", +"eastern hog-nosed snake", +"smooth green snake", +"kingsnake", +"garter snake", +"water snake", +"vine snake", +"night snake", +"boa constrictor", +"African rock python", +"Indian cobra", +"green mamba", +"sea snake", +"Saharan horned viper", +"eastern diamondback rattlesnake", +"sidewinder", +"trilobite", +"harvestman", +"scorpion", +"yellow garden spider", +"barn spider", +"European garden spider", +"southern black widow", +"tarantula", +"wolf spider", +"tick", +"centipede", +"black grouse", +"ptarmigan", +"ruffed grouse", +"prairie grouse", +"peacock", +"quail", +"partridge", +"grey parrot", +"macaw", +"sulphur-crested cockatoo", +"lorikeet", +"coucal", +"bee eater", +"hornbill", +"hummingbird", +"jacamar", +"toucan", +"duck", +"red-breasted merganser", +"goose", +"black swan", +"tusker", +"echidna", +"platypus", +"wallaby", +"koala", +"wombat", +"jellyfish", +"sea anemone", +"brain coral", +"flatworm", +"nematode", +"conch", +"snail", +"slug", +"sea slug", +"chiton", +"chambered nautilus", +"Dungeness crab", +"rock crab", +"fiddler crab", +"red king crab", +"American lobster", +"spiny lobster", +"crayfish", +"hermit crab", +"isopod", +"white stork", +"black stork", +"spoonbill", +"flamingo", +"little blue heron", +"great egret", +"bittern", +"crane (bird)", +"limpkin", +"common gallinule", +"American coot", +"bustard", +"ruddy turnstone", +"dunlin", +"common redshank", +"dowitcher", +"oystercatcher", +"pelican", +"king penguin", +"albatross", +"grey whale", +"killer whale", +"dugong", +"sea lion", +"Chihuahua", +"Japanese Chin", +"Maltese", +"Pekingese", +"Shih Tzu", +"King Charles Spaniel", +"Papillon", +"toy terrier", +"Rhodesian Ridgeback", +"Afghan Hound", +"Basset Hound", +"Beagle", +"Bloodhound", +"Bluetick Coonhound", +"Black and Tan Coonhound", +"Treeing Walker Coonhound", +"English foxhound", +"Redbone Coonhound", +"borzoi", +"Irish Wolfhound", +"Italian Greyhound", +"Whippet", +"Ibizan Hound", +"Norwegian Elkhound", +"Otterhound", +"Saluki", +"Scottish Deerhound", +"Weimaraner", +"Staffordshire Bull Terrier", +"American Staffordshire Terrier", +"Bedlington Terrier", +"Border Terrier", +"Kerry Blue Terrier", +"Irish Terrier", +"Norfolk Terrier", +"Norwich Terrier", +"Yorkshire Terrier", +"Wire Fox Terrier", +"Lakeland Terrier", +"Sealyham Terrier", +"Airedale Terrier", +"Cairn Terrier", +"Australian Terrier", +"Dandie Dinmont Terrier", +"Boston Terrier", +"Miniature Schnauzer", +"Giant Schnauzer", +"Standard Schnauzer", +"Scottish Terrier", +"Tibetan Terrier", +"Australian Silky Terrier", +"Soft-coated Wheaten Terrier", +"West Highland White Terrier", +"Lhasa Apso", +"Flat-Coated Retriever", +"Curly-coated Retriever", +"Golden Retriever", +"Labrador Retriever", +"Chesapeake Bay Retriever", +"German Shorthaired Pointer", +"Vizsla", +"English Setter", +"Irish Setter", +"Gordon Setter", +"Brittany", +"Clumber Spaniel", +"English Springer Spaniel", +"Welsh Springer Spaniel", +"Cocker Spaniels", +"Sussex Spaniel", +"Irish Water Spaniel", +"Kuvasz", +"Schipperke", +"Groenendael", +"Malinois", +"Briard", +"Australian Kelpie", +"Komondor", +"Old English Sheepdog", +"Shetland Sheepdog", +"collie", +"Border Collie", +"Bouvier des Flandres", +"Rottweiler", +"German Shepherd Dog", +"Dobermann", +"Miniature Pinscher", +"Greater Swiss Mountain Dog", +"Bernese Mountain Dog", +"Appenzeller Sennenhund", +"Entlebucher Sennenhund", +"Boxer", +"Bullmastiff", +"Tibetan Mastiff", +"French Bulldog", +"Great Dane", +"St. Bernard", +"husky", +"Alaskan Malamute", +"Siberian Husky", +"Dalmatian", +"Affenpinscher", +"Basenji", +"pug", +"Leonberger", +"Newfoundland", +"Pyrenean Mountain Dog", +"Samoyed", +"Pomeranian", +"Chow Chow", +"Keeshond", +"Griffon Bruxellois", +"Pembroke Welsh Corgi", +"Cardigan Welsh Corgi", +"Toy Poodle", +"Miniature Poodle", +"Standard Poodle", +"Mexican hairless dog", +"grey wolf", +"Alaskan tundra wolf", +"red wolf", +"coyote", +"dingo", +"dhole", +"African wild dog", +"hyena", +"red fox", +"kit fox", +"Arctic fox", +"grey fox", +"tabby cat", +"tiger cat", +"Persian cat", +"Siamese cat", +"Egyptian Mau", +"cougar", +"lynx", +"leopard", +"snow leopard", +"jaguar", +"lion", +"tiger", +"cheetah", +"brown bear", +"American black bear", +"polar bear", +"sloth bear", +"mongoose", +"meerkat", +"tiger beetle", +"ladybug", +"ground beetle", +"longhorn beetle", +"leaf beetle", +"dung beetle", +"rhinoceros beetle", +"weevil", +"fly", +"bee", +"ant", +"grasshopper", +"cricket", +"stick insect", +"cockroach", +"mantis", +"cicada", +"leafhopper", +"lacewing", +"dragonfly", +"damselfly", +"red admiral", +"ringlet", +"monarch butterfly", +"small white", +"sulphur butterfly", +"gossamer-winged butterfly", +"starfish", +"sea urchin", +"sea cucumber", +"cottontail rabbit", +"hare", +"Angora rabbit", +"hamster", +"porcupine", +"fox squirrel", +"marmot", +"beaver", +"guinea pig", +"common sorrel", +"zebra", +"pig", +"wild boar", +"warthog", +"hippopotamus", +"ox", +"water buffalo", +"bison", +"ram", +"bighorn sheep", +"Alpine ibex", +"hartebeest", +"impala", +"gazelle", +"dromedary", +"llama", +"weasel", +"mink", +"European polecat", +"black-footed ferret", +"otter", +"skunk", +"badger", +"armadillo", +"three-toed sloth", +"orangutan", +"gorilla", +"chimpanzee", +"gibbon", +"siamang", +"guenon", +"patas monkey", +"baboon", +"macaque", +"langur", +"black-and-white colobus", +"proboscis monkey", +"marmoset", +"white-headed capuchin", +"howler monkey", +"titi", +"Geoffroy's spider monkey", +"common squirrel monkey", +"ring-tailed lemur", +"indri", +"Asian elephant", +"African bush elephant", +"red panda", +"giant panda", +"snoek", +"eel", +"coho salmon", +"rock beauty", +"clownfish", +"sturgeon", +"garfish", +"lionfish", +"pufferfish", +"abacus", +"abaya", +"academic gown", +"accordion", +"acoustic guitar", +"aircraft carrier", +"airliner", +"airship", +"altar", +"ambulance", +"amphibious vehicle", +"analog clock", +"apiary", +"apron", +"waste container", +"assault rifle", +"backpack", +"bakery", +"balance beam", +"balloon", +"ballpoint pen", +"Band-Aid", +"banjo", +"baluster", +"barbell", +"barber chair", +"barbershop", +"barn", +"barometer", +"barrel", +"wheelbarrow", +"baseball", +"basketball", +"bassinet", +"bassoon", +"swimming cap", +"bath towel", +"bathtub", +"station wagon", +"lighthouse", +"beaker", +"military cap", +"beer bottle", +"beer glass", +"bell-cot", +"bib", +"tandem bicycle", +"bikini", +"ring binder", +"binoculars", +"birdhouse", +"boathouse", +"bobsleigh", +"bolo tie", +"poke bonnet", +"bookcase", +"bookstore", +"bottle cap", +"bow", +"bow tie", +"brass", +"bra", +"breakwater", +"breastplate", +"broom", +"bucket", +"buckle", +"bulletproof vest", +"high-speed train", +"butcher shop", +"taxicab", +"cauldron", +"candle", +"cannon", +"canoe", +"can opener", +"cardigan", +"car mirror", +"carousel", +"tool kit", +"carton", +"car wheel", +"automated teller machine", +"cassette", +"cassette player", +"castle", +"catamaran", +"CD player", +"cello", +"mobile phone", +"chain", +"chain-link fence", +"chain mail", +"chainsaw", +"chest", +"chiffonier", +"chime", +"china cabinet", +"Christmas stocking", +"church", +"movie theater", +"cleaver", +"cliff dwelling", +"cloak", +"clogs", +"cocktail shaker", +"coffee mug", +"coffeemaker", +"coil", +"combination lock", +"computer keyboard", +"confectionery store", +"container ship", +"convertible", +"corkscrew", +"cornet", +"cowboy boot", +"cowboy hat", +"cradle", +"crane (machine)", +"crash helmet", +"crate", +"infant bed", +"Crock Pot", +"croquet ball", +"crutch", +"cuirass", +"dam", +"desk", +"desktop computer", +"rotary dial telephone", +"diaper", +"digital clock", +"digital watch", +"dining table", +"dishcloth", +"dishwasher", +"disc brake", +"dock", +"dog sled", +"dome", +"doormat", +"drilling rig", +"drum", +"drumstick", +"dumbbell", +"Dutch oven", +"electric fan", +"electric guitar", +"electric locomotive", +"entertainment center", +"envelope", +"espresso machine", +"face powder", +"feather boa", +"filing cabinet", +"fireboat", +"fire engine", +"fire screen sheet", +"flagpole", +"flute", +"folding chair", +"football helmet", +"forklift", +"fountain", +"fountain pen", +"four-poster bed", +"freight car", +"French horn", +"frying pan", +"fur coat", +"garbage truck", +"gas mask", +"gas pump", +"goblet", +"go-kart", +"golf ball", +"golf cart", +"gondola", +"gong", +"gown", +"grand piano", +"greenhouse", +"grille", +"grocery store", +"guillotine", +"barrette", +"hair spray", +"half-track", +"hammer", +"hamper", +"hair dryer", +"hand-held computer", +"handkerchief", +"hard disk drive", +"harmonica", +"harp", +"harvester", +"hatchet", +"holster", +"home theater", +"honeycomb", +"hook", +"hoop skirt", +"horizontal bar", +"horse-drawn vehicle", +"hourglass", +"iPod", +"clothes iron", +"jack-o'-lantern", +"jeans", +"jeep", +"T-shirt", +"jigsaw puzzle", +"pulled rickshaw", +"joystick", +"kimono", +"knee pad", +"knot", +"lab coat", +"ladle", +"lampshade", +"laptop computer", +"lawn mower", +"lens cap", +"paper knife", +"library", +"lifeboat", +"lighter", +"limousine", +"ocean liner", +"lipstick", +"slip-on shoe", +"lotion", +"speaker", +"loupe", +"sawmill", +"magnetic compass", +"mail bag", +"mailbox", +"tights", +"tank suit", +"manhole cover", +"maraca", +"marimba", +"mask", +"match", +"maypole", +"maze", +"measuring cup", +"medicine chest", +"megalith", +"microphone", +"microwave oven", +"military uniform", +"milk can", +"minibus", +"miniskirt", +"minivan", +"missile", +"mitten", +"mixing bowl", +"mobile home", +"Model T", +"modem", +"monastery", +"monitor", +"moped", +"mortar", +"square academic cap", +"mosque", +"mosquito net", +"scooter", +"mountain bike", +"tent", +"computer mouse", +"mousetrap", +"moving van", +"muzzle", +"nail", +"neck brace", +"necklace", +"nipple", +"notebook computer", +"obelisk", +"oboe", +"ocarina", +"odometer", +"oil filter", +"organ", +"oscilloscope", +"overskirt", +"bullock cart", +"oxygen mask", +"packet", +"paddle", +"paddle wheel", +"padlock", +"paintbrush", +"pajamas", +"palace", +"pan flute", +"paper towel", +"parachute", +"parallel bars", +"park bench", +"parking meter", +"passenger car", +"patio", +"payphone", +"pedestal", +"pencil case", +"pencil sharpener", +"perfume", +"Petri dish", +"photocopier", +"plectrum", +"Pickelhaube", +"picket fence", +"pickup truck", +"pier", +"piggy bank", +"pill bottle", +"pillow", +"ping-pong ball", +"pinwheel", +"pirate ship", +"pitcher", +"hand plane", +"planetarium", +"plastic bag", +"plate rack", +"plow", +"plunger", +"Polaroid camera", +"pole", +"police van", +"poncho", +"billiard table", +"soda bottle", +"pot", +"potter's wheel", +"power drill", +"prayer rug", +"printer", +"prison", +"projectile", +"projector", +"hockey puck", +"punching bag", +"purse", +"quill", +"quilt", +"race car", +"racket", +"radiator", +"radio", +"radio telescope", +"rain barrel", +"recreational vehicle", +"reel", +"reflex camera", +"refrigerator", +"remote control", +"restaurant", +"revolver", +"rifle", +"rocking chair", +"rotisserie", +"eraser", +"rugby ball", +"ruler", +"running shoe", +"safe", +"safety pin", +"salt shaker", +"sandal", +"sarong", +"saxophone", +"scabbard", +"weighing scale", +"school bus", +"schooner", +"scoreboard", +"CRT screen", +"screw", +"screwdriver", +"seat belt", +"sewing machine", +"shield", +"shoe store", +"shoji", +"shopping basket", +"shopping cart", +"shovel", +"shower cap", +"shower curtain", +"ski", +"ski mask", +"sleeping bag", +"slide rule", +"sliding door", +"slot machine", +"snorkel", +"snowmobile", +"snowplow", +"soap dispenser", +"soccer ball", +"sock", +"solar thermal collector", +"sombrero", +"soup bowl", +"space bar", +"space heater", +"space shuttle", +"spatula", +"motorboat", +"spider web", +"spindle", +"sports car", +"spotlight", +"stage", +"steam locomotive", +"through arch bridge", +"steel drum", +"stethoscope", +"scarf", +"stone wall", +"stopwatch", +"stove", +"strainer", +"tram", +"stretcher", +"couch", +"stupa", +"submarine", +"suit", +"sundial", +"sunglass", +"sunglasses", +"sunscreen", +"suspension bridge", +"mop", +"sweatshirt", +"swimsuit", +"swing", +"switch", +"syringe", +"table lamp", +"tank", +"tape player", +"teapot", +"teddy bear", +"television", +"tennis ball", +"thatched roof", +"front curtain", +"thimble", +"threshing machine", +"throne", +"tile roof", +"toaster", +"tobacco shop", +"toilet seat", +"torch", +"totem pole", +"tow truck", +"toy store", +"tractor", +"semi-trailer truck", +"tray", +"trench coat", +"tricycle", +"trimaran", +"tripod", +"triumphal arch", +"trolleybus", +"trombone", +"tub", +"turnstile", +"typewriter keyboard", +"umbrella", +"unicycle", +"upright piano", +"vacuum cleaner", +"vase", +"vault", +"velvet", +"vending machine", +"vestment", +"viaduct", +"violin", +"volleyball", +"waffle iron", +"wall clock", +"wallet", +"wardrobe", +"military aircraft", +"sink", +"washing machine", +"water bottle", +"water jug", +"water tower", +"whiskey jug", +"whistle", +"wig", +"window screen", +"window shade", +"Windsor tie", +"wine bottle", +"wing", +"wok", +"wooden spoon", +"wool", +"split-rail fence", +"shipwreck", +"yawl", +"yurt", +"website", +"comic book", +"crossword", +"traffic sign", +"traffic light", +"dust jacket", +"menu", +"plate", +"guacamole", +"consomme", +"hot pot", +"trifle", +"ice cream", +"ice pop", +"baguette", +"bagel", +"pretzel", +"cheeseburger", +"hot dog", +"mashed potato", +"cabbage", +"broccoli", +"cauliflower", +"zucchini", +"spaghetti squash", +"acorn squash", +"butternut squash", +"cucumber", +"artichoke", +"bell pepper", +"cardoon", +"mushroom", +"Granny Smith", +"strawberry", +"orange", +"lemon", +"fig", +"pineapple", +"banana", +"jackfruit", +"custard apple", +"pomegranate", +"hay", +"carbonara", +"chocolate syrup", +"dough", +"meatloaf", +"pizza", +"pot pie", +"burrito", +"red wine", +"espresso", +"cup", +"eggnog", +"alp", +"bubble", +"cliff", +"coral reef", +"geyser", +"lakeshore", +"promontory", +"shoal", +"seashore", +"valley", +"volcano", +"baseball player", +"bridegroom", +"scuba diver", +"rapeseed", +"daisy", +"yellow lady's slipper", +"corn", +"acorn", +"rose hip", +"horse chestnut seed", +"coral fungus", +"agaric", +"gyromitra", +"stinkhorn mushroom", +"earth star", +"hen-of-the-woods", +"bolete", +"ear", +"toilet paper"] diff --git a/kerascv/makelist.py b/kerascv/makelist.py new file mode 100644 index 00000000..8498fa24 --- /dev/null +++ b/kerascv/makelist.py @@ -0,0 +1,10 @@ +''' +Use this script to generate a list of all XML files in a folder. +''' + +from glob import glob + +files = glob('*.xml') +with open('xml_list.txt', 'w') as f: + for fn in files: + f.write("%s\n" % fn) \ No newline at end of file diff --git a/kerascv/pascal2coco.py b/kerascv/pascal2coco.py new file mode 100644 index 00000000..3ffbd3b8 --- /dev/null +++ b/kerascv/pascal2coco.py @@ -0,0 +1,152 @@ +# adapted from https://blog.roboflow.com/how-to-convert-annotations-from-voc-xml-to-coco-json/ + +import os +import argparse +import json +import xml.etree.ElementTree as ET +from typing import Dict, List +from tqdm import tqdm +import re + + +def get_label2id(labels_path: str) -> Dict[str, int]: + """id is 1 start""" + with open(labels_path, 'r') as f: + labels_str = f.read().split() + labels_ids = list(range(0, len(labels_str))) + return dict(zip(labels_str, labels_ids)) + + +def get_annpaths(ann_dir_path: str = None, + ann_ids_path: str = None, + ext: str = '', + annpaths_list_path: str = None) -> List[str]: + # If use annotation paths list + if annpaths_list_path is not None: + with open(annpaths_list_path, 'r') as f: + ann_paths = f.read().split() + return ann_paths + + # If use annotaion ids list + ext_with_dot = '.' + ext if ext != '' else '' + with open(ann_ids_path, 'r') as f: + ann_ids = f.read().split() + ann_paths = [os.path.join(ann_dir_path, aid+ext_with_dot) for aid in ann_ids] + return ann_paths + + +def get_image_info(annotation_root, extract_num_from_imgid=True): + path = annotation_root.findtext('path') + if path is None: + filename = annotation_root.findtext('filename') + else: + filename = os.path.basename(path) + img_name = os.path.basename(filename) + img_id = os.path.splitext(img_name)[0] + if extract_num_from_imgid and isinstance(img_id, str): + img_id = int(re.findall(r'\d+', img_id)[0]) + + size = annotation_root.find('size') + width = int(size.findtext('width')) + height = int(size.findtext('height')) + + image_info = { + 'file_name': filename, + 'height': height, + 'width': width, + 'id': img_id + } + return image_info + + +def get_coco_annotation_from_obj(obj, label2id): + label = obj.findtext('name') + assert label in label2id, f"Error: {label} is not in label2id !" + category_id = label2id[label] + bndbox = obj.find('bndbox') + xmin = int(bndbox.findtext('xmin')) - 1 + ymin = int(bndbox.findtext('ymin')) - 1 + xmax = int(bndbox.findtext('xmax')) + ymax = int(bndbox.findtext('ymax')) + assert xmax > xmin and ymax > ymin, f"Box size error !: (xmin, ymin, xmax, ymax): {xmin, ymin, xmax, ymax}" + o_width = xmax - xmin + o_height = ymax - ymin + ann = { + 'area': o_width * o_height, + 'iscrowd': 0, + 'bbox': [xmin, ymin, o_width, o_height], + 'category_id': category_id, + 'ignore': 0, + 'segmentation': [] # This script is not for segmentation + } + return ann + + +def convert_xmls_to_cocojson(annotation_paths: List[str], + label2id: Dict[str, int], + output_jsonpath: str, + extract_num_from_imgid: bool = True): + output_json_dict = { + "images": [], + "type": "instances", + "annotations": [], + "categories": [] + } + bnd_id = 1 # START_BOUNDING_BOX_ID, TODO input as args ? + print('Start converting !') + for a_path in tqdm(annotation_paths): + # Read annotation xml + ann_tree = ET.parse(a_path) + ann_root = ann_tree.getroot() + + img_info = get_image_info(annotation_root=ann_root, + extract_num_from_imgid=extract_num_from_imgid) + img_id = img_info['id'] + output_json_dict['images'].append(img_info) + + for obj in ann_root.findall('object'): + ann = get_coco_annotation_from_obj(obj=obj, label2id=label2id) + ann.update({'image_id': img_id, 'id': bnd_id}) + output_json_dict['annotations'].append(ann) + bnd_id = bnd_id + 1 + + for label, label_id in label2id.items(): + category_info = {'supercategory': 'none', 'id': label_id, 'name': label} + output_json_dict['categories'].append(category_info) + + with open(output_jsonpath, 'w') as f: + output_json = json.dumps(output_json_dict) + f.write(output_json) + + +def main(): + parser = argparse.ArgumentParser( + description='This script support converting voc format xmls to coco format json') + parser.add_argument('--ann_dir', type=str, default=None, + help='path to annotation files directory. It is not need when use --ann_paths_list') + parser.add_argument('--ann_ids', type=str, default=None, + help='path to annotation files ids list. It is not need when use --ann_paths_list') + parser.add_argument('--ann_paths_list', type=str, default=None, + help='path of annotation paths list. It is not need when use --ann_dir and --ann_ids') + parser.add_argument('--labels', type=str, default=None, + help='path to label list.') + parser.add_argument('--output', type=str, default='output.json', help='path to output json file') + parser.add_argument('--ext', type=str, default='', help='additional extension of annotation file') + args = parser.parse_args() + label2id = get_label2id(labels_path=args.labels) + ann_paths = get_annpaths( + ann_dir_path=args.ann_dir, + ann_ids_path=args.ann_ids, + ext=args.ext, + annpaths_list_path=args.ann_paths_list + ) + convert_xmls_to_cocojson( + annotation_paths=ann_paths, + label2id=label2id, + output_jsonpath=args.output, + extract_num_from_imgid=True + ) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/linear_algebra/WHERE ARE THE NOTEBOOKS.txt b/linear_algebra/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/linear_algebra/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/linear_algebra/extra_reading.txt b/linear_algebra/extra_reading.txt new file mode 100644 index 00000000..865e98be --- /dev/null +++ b/linear_algebra/extra_reading.txt @@ -0,0 +1,6 @@ +Introduction to Linear Algebra by Gilbert Strang +https://amzn.to/2G3bvW1 + +Still Don't Understand Gravity? This Will Help +- this is included not because it's about calculus, but because it's yet another educator explaining why practice is important +https://www.youtube.com/watch?v=cP2uVarXi1A \ No newline at end of file diff --git a/linear_regression_class/systolic.py b/linear_regression_class/systolic.py index b7451837..7d594670 100644 --- a/linear_regression_class/systolic.py +++ b/linear_regression_class/systolic.py @@ -19,7 +19,7 @@ import numpy as np import pandas as pd -df = pd.read_excel('mlr02.xls') +df = pd.read_excel('mlr02.xls', engine='xlrd') X = df.values # using age to predict systolic blood pressure diff --git a/matrix_calculus/extra_reading.txt b/matrix_calculus/extra_reading.txt new file mode 100644 index 00000000..a19af06d --- /dev/null +++ b/matrix_calculus/extra_reading.txt @@ -0,0 +1,2 @@ +The Matrix Cookbook +https://www.math.uwaterloo.ca/~hwolkowi/matrixcookbook.pdf \ No newline at end of file diff --git a/naive_bayes/WHERE ARE THE NOTEBOOKS.txt b/naive_bayes/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/naive_bayes/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/naive_bayes/extra_reading.txt b/naive_bayes/extra_reading.txt new file mode 100644 index 00000000..52e5228b --- /dev/null +++ b/naive_bayes/extra_reading.txt @@ -0,0 +1,8 @@ +Complement Naive Bayes +https://people.csail.mit.edu/jrennie/papers/icml03-nb.pdf + +Semi-Supervised Learning with Naive Bayes +http://www.kamalnigam.com/papers/emcat-aaai98.pdf + +An empirical study of the naive Bayes classifier +https://faculty.cc.gatech.edu/~isbell/reading/papers/Rish.pdf \ No newline at end of file diff --git a/nlp_class2/neural_network2.py b/nlp_class2/neural_network2.py index 573dd9e9..159dc571 100644 --- a/nlp_class2/neural_network2.py +++ b/nlp_class2/neural_network2.py @@ -96,18 +96,23 @@ def softmax(a): # # original: W1 = W1 - lr * inputs.T.dot(dhidden) # VxN NxD --> VxD # fastest way + W1_copy = W1.copy() np.subtract.at(W1, inputs, lr * dhidden) - # test this - # i = 0 - # for w in inputs: # don't include end token - # W1[w] = W1[w] - lr * dhidden[i] - # i += 1 - # vs this + # W1_test = W1_copy.copy() # oh_inputs = np.zeros((n - 1, V)) # oh_inputs[np.arange(n - 1), sentence[:n-1]] = 1 - # W1 = W1 - lr * oh_inputs.T.dot(dhidden) + # W1_test = W1_test - lr * oh_inputs.T.dot(dhidden) + # assert(np.allclose(W1_test, W1)) + + # vs this + # W1_test = W1_copy.copy() + # i = 0 + # for w in inputs: # don't include end token + # W1_test[w] = W1_test[w] - lr * dhidden[i] + # i += 1 + # assert(np.allclose(W1_test, W1)) # keep track of the bigram loss # only do it for the first epoch to avoid redundancy diff --git a/nlp_v2/WHERE ARE THE NOTEBOOKS.txt b/nlp_v2/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/nlp_v2/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/nlp_v2/extra_reading.txt b/nlp_v2/extra_reading.txt index 62a145b9..d7d382f9 100644 --- a/nlp_v2/extra_reading.txt +++ b/nlp_v2/extra_reading.txt @@ -10,6 +10,12 @@ https://web.eecs.umich.edu/~mihalcea/papers/mihalcea.emnlp04.pdf Variations of the Similarity Function of TextRank for Automated Summarization https://arxiv.org/abs/1602.03606 +Generic Text Summarization Using Relevance Measure and Latent Semantic Analysis +https://www.cs.bham.ac.uk/~pxt/IDA/text_summary.pdf + +Using Latent Semantic Analysis in Text Summarization and Summary Evaluation +http://textmining.zcu.cz/publications/isim.pdf + Spam Filtering with Naive Bayes – Which Naive Bayes? http://www2.aueb.gr/users/ion/docs/ceas2006_paper.pdf @@ -29,4 +35,7 @@ Efficient Estimation of Word Representations in Vector Space (word2vec) https://arxiv.org/abs/1301.3781 GloVe: Global Vectors for Word Representation (GloVe) -https://nlp.stanford.edu/pubs/glove.pdf \ No newline at end of file +https://nlp.stanford.edu/pubs/glove.pdf + +Deep Learning with Tensorflow, a bit more in-depth +https://deeplearningcourses.com/c/deep-learning-tensorflow-2 \ No newline at end of file diff --git a/openai/extra_reading.txt b/openai/extra_reading.txt new file mode 100644 index 00000000..776b62c7 --- /dev/null +++ b/openai/extra_reading.txt @@ -0,0 +1,21 @@ +How to Set Environment Variables Permanently in Windows, Linux, and Mac +https://lazyprogrammer.me/how-to-set-environment-variables-permanently-in-windows-linux-and-mac/ + +How to make your completions outputs consistent with the new seed parameter +https://cookbook.openai.com/examples/reproducible_outputs_with_the_seed_parameter + +What is Temperature in NLP / LLMs? +https://medium.com/@lazyprogrammerofficial/what-is-temperature-in-nlp-llms-aa2a7212e687 + +Large Language Models are Zero-Shot Reasoners (CoT) +https://arxiv.org/abs/2205.11916 + +Chain-of-Thought Prompting Elicits Reasoning in Large Language Models +https://arxiv.org/abs/2201.11903 + +A much better example of "ELI5" +https://www.reddit.com/r/ChatGPT/comments/1c5s51g/my_mother_and_i_had_difficulty_understanding_my + +What is RAG? — Retrieval-Augmented Generation Explained +https://medium.com/@lazyprogrammerofficial/what-is-rag-retrieval-augmented-generation-explained-148c8bb9c00f +https://lazyprogrammer.me/what-is-rag-retrieval-augmented-generation-explained/ \ No newline at end of file diff --git a/openai/fight.mp4 b/openai/fight.mp4 new file mode 100644 index 00000000..24d83be4 Binary files /dev/null and b/openai/fight.mp4 differ diff --git a/openai/finance.png b/openai/finance.png new file mode 100644 index 00000000..b274c4b9 Binary files /dev/null and b/openai/finance.png differ diff --git a/openai/handwriting.jpg b/openai/handwriting.jpg new file mode 100644 index 00000000..2e92adf4 Binary files /dev/null and b/openai/handwriting.jpg differ diff --git a/openai/physics_problem.jpeg b/openai/physics_problem.jpeg new file mode 100644 index 00000000..3f6d3200 Binary files /dev/null and b/openai/physics_problem.jpeg differ diff --git a/openai/replies.json b/openai/replies.json new file mode 100644 index 00000000..27d6761c --- /dev/null +++ b/openai/replies.json @@ -0,0 +1,206 @@ +[ + { + "review": "(1) His answers are sometimes antagonistic but the guy wants us to think by ourselves. I feel he was guided by questions from students with very little background on the subject. (2) Links are not updated. I understand not updated them on the videos, but on the git repository and the scripts, it should have them updated. (3) Explanations are great, with a few inconsistencies when compared to Gemini.google.com understanding. (4) The course content in general is great.", + "response": "(1) I think all students should respect other students taking this course. All students deserve to have their questions answered, and no student can expect to have this course personalized to their own background.\n\n(2) This is incorrect, and you were already instructed on the Q&A to ensure you were looking at the correct repository with the most up-to-date files.\n\n(3) LLMs are known for hallucinating, and their output cannot be trusted, especially if you don't know what you're doing. Instead, you should be using the Q&A to rectify these issues, which is why it's the #1 rule in 'how to succeed in this course'." + }, + { + "review": "You should have explained in the introduction video that, you have not yet figured out Stock forecasting, so explaining your (thoughts or beliefs or work) in this course. But marketing in great way , nothing in content other than playing with data.", + "response": "Try paying attention and understanding the course. If you still believe there's some magic algorithm to perfectly predict stock prices and I \"just haven't figured it out yet\", you clearly weren't listening, know absolutely nothing about finance, and hence, spreading misinformation to readers." + }, + { + "review": "I'm really disappointed. The last update of your codes was 9 years ago. Nothing is running. I tried file after file - nothing works. I don't think you could even continue to sell these courses. Unfortunately, I can no longer cancel the current course, but I will cancel the next course. Your courses do not meet basic standards. Too bad.", + "response": "> The last update of your codes was 9 years ago.\n\nNOTE: Our friend here just doesn't know how to use Git properly. My ML Github repo was CREATED 9 years ago (long before I even started making courses)." + }, + { + "review": "nao é claro ainda como fazer o donlow de githum", + "response": "Thanks for the feedback! Please re-watch the lecture \"Where to get the code / notebooks\" carefully and follow the instructions. It clearly states 5 times (yes, that many times) that the notebooks are not on Github, but rather, are accessed via the code link." + }, + { + "review": "It is a good course about RL, as all his courses, but if you are here for the Trading agent, don't buy it... very basic code and does not really work.", + "response": "Thanks for your feedback! However, it seems you are basing your rating around your own misconceptions and naivete surrounding trading and finance, rather than the quality of the course itself." + }, + { + "review": "Need to explain more about the topic. CNN is more theoretical in the course than programming.", + "response": "Incorrect. There are equal parts theory and programming. Every \"theoretical\" concept is implemented in code. And obviously, you must understand \"what\" you are coding before you code it. Please pay attention to improve your understanding, thanks!" + }, + { + "review": "The content is ok but the links between videos and sections aren't always obvious. I like the fact that it goes in dept on my subjects but the quality of the audio isn't always good enough. I would still recommend to someone that really want to have a better understanding of AI/ML or specifically logistic regression but expect some extra reading if you really want to understand all the concepts well.", + "response": "You should probably revisit the \"introduction and outline\" of the course if you've forgotten the structure of the course. There's only \"extra reading\" if you do not sufficiently meet the prerequisites." + }, + { + "review": "I expected some coding and practice but most of the course till now is just theory", + "response": "That's incorrect, and this is even visible from simply looking at the lecture titles. There are equal parts theory and code. First we discuss \"what\" we will code, then we code it. Obviously, you can't write code without knowing what you're coding first... Please pay attention to improve your understanding, thanks!" + }, + { + "review": "It is all over the place ... not very structured and i have IT and python background , still finding difficult to follow ... i wonder how the Deep learning course will be", + "response": "Unclear why you're having trouble following the structure of such a simple short course. There are only 4 sections: Numpy, Matplotlib, Pandas, and Scipy. Please pay attention to improve your understanding, thanks!" + }, + { + "review": "Content is good so far, but lecturer seems hung up on the behaviors of the participants which is not helping the instruction time.", + "response": "It's important to remember that the course isn't customized for you individually. Therefore, it should be expected that common problems that afflict a non-trivial number of students will be addressed." + }, + { + "review": "Explanation is not clear as we are beginners. May be improve better to understand clearly.", + "response": "Thanks for the feedback! Please ensure you meet the prerequisites as listed twice in the course description and several more times in lectures such as \"how to succeed in this course\"." + }, + { + "review": "Much was great, some frequently explained by referring to other courses as well as skipping some code blocks or instrumental variables, which were readily explained in chat gpt by asking if to add copious explanatory comments. Most, but certainly not all AI ML course instructors are more concerned with taking the time to explain finer details of the code. Early parts on ANN and CNN were excellent in presentation although this was simpler material. In the course was more presenting and explaining than teaching how to code the models, both necessary individually and together sufficient for a solid learning experience. Perhaps sacrifice some optional topics for more time indepth to the course essentials - quantity versus quality.", + "response": "Unclear whether you wrote this comment for the wrong course, as there are no sections about ANNs or CNNs in this course... Furthermore, this course is not about in-depth theory - please check the course description and prerequisites, thanks!" + }, + { + "review": "Some more details about math equations could be added", + "response": "Thanks for the feedback! Please ensure you meet the prerequisites as listed twice in the course description and several more times in lectures such as \"how to succeed in this course\". Furthermore, you may want to read the course description that explains that this course is about Tensorflow 2, not the math behind deep learning. I already have courses on that, so check those out instead." + }, + { + "review": "Teaches only Syntax and not any ML or theory behind how any of the Neural Network architectures work.", + "response": "Incorrect. This course gives an overview of theory, and furthermore, I already have 15+ in-depth DL courses that go into the math behind DL. Luckily, this is all in the course description, which I'm sure you've diligently read. ;)" + }, + { + "review": "It was a good match for my current abilities. I could not access the live python notebooks or links used. I would have appreciated solutions to the end of section exercises. Overall though the instructor is very knowledgeable and the course is free so I can't complain.", + "response": "The key is to follow the instructions. All notebooks and exercise solutions are provided, if you can just follow the instructions on how to get them (clicking links). It really is very easy, it just requires paying attention. :)" + }, + { + "review": "The Neural Network part is not very clear", + "response": "This course doesn't talk about neural networks..." + }, + { + "review": "need more examples", + "response": "The course is full of examples, please use the Q&A if you have difficulties understanding them" + }, + { + "review": "Could use a bit more time spent on explaining certain concepts, like Box-Cox, giving more intuition and explanation of why that is useful", + "response": "Please use the Q&A to inquire about your misunderstandings, as stated in \"how to succeed in this course\"." + }, + { + "review": "Interesting course with lots of examples and lectures. Although some parts of the course become repetitive. There are lectures where he explains the code step by step and then goes on to repeat the same thing in the \"... in Python\" lectures. It would have been nice if he had proposed other exercises with a different dataset than the lectures, even though he does not provide the solution. It is fine to say that we should try to write the code ourselves first and then check the solution, but when this is reduced to copy and paste from the previous lecture it seems ridiculous to me.", + "response": "This is a practical course, meaning that you are shown the code and can do with it what you wish (there's no way to \"exercise\" writing library code without first being shown the syntax, which doesn't make any sense). Additionally, repetition is a research-backed learning technique: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8442015/ Furthermore, please remember that the course is not customized to you. Therefore, if you personally choose to avoid repetition, you are free to do so, nobody is stopping you." + }, + { + "review": "I enjoyed the author explanation on the differences between statistics regression and ML regression content. But I think the lecture on the differences was pedantic and unnecessary even. The content list and summary to this lecture is where the distinction could be made. Instead, it was spent ranting within the lecture, how does that provide any value and meaningful experience? Worry not about the review, if the content is good, the review would come.", + "response": "> But I think the lecture on the differences was pedantic and unnecessary even.\n\nPlease remember, the course is not customized for you personally, it's for all students and therefore addresses common student mistakes, irrespective of your personal needs. Obviously, I have to answer ALL student questions, whether or not you personally find the question/answer helpful." + }, + { + "review": "The instructor seems inadequately prepared for each segment of the course. There is a noticeable absence of demonstrations that are essential for a comprehensive understanding of the material. Furthermore, there is a disproportionate emphasis on paid websites over free alternatives, raising concerns about potential conflicts of interest due to affiliate marketing associations with these paid platforms.", + "response": "Everything is demonstrated in Colab notebooks. I challenge you to list specific examples instead of vague accusations like \"inadequately prepared\" and \"noticeable absence of demonstrations\".\n\n> disproportionate emphasis on paid websites over free alternatives\n\nThat is merely what you are paying attention to and triggered by. Most tools in the course are free or have free alternatives. Furthermore, I don't choose what's free, they are not my companies, so I am unsure why you think this is my fault...?" + }, + { + "review": "I have taken this course and have spent lot of hrs and can tell that, this 12 hrs course will take lot of time to understand and complete (150 hrs). This can be done if we have 100% free time for 4 weeks. Good thing is if you have little idea of Calculus and we flow what is being taught, this course will make us ready to understand ML. Having said that the instructor should again go back and try to minimize the un-necessary or repetitive content.", + "response": "There is no unnecessary or repetitive content, and if you believe there is, you should use the Q&A to clear up any misunderstandings as instructed in the \"how to succeed in this course\" video." + }, + { + "review": "Content is inconsistent in difficulty. Instructor is not good at explaining highly complicated topics that require a lot of Mathematics.", + "response": "Thanks for the feedback! Please ensure you meet the prerequisites as listed twice in the course description and several more times in lectures such as \"how to succeed in this course\". Please recall that each section is denoted as \"beginner\", \"intermediate\", or \"advanced\" (as stated in the intro). One must choose according to their own skill level. This obvious lack of attention explains why you are having trouble understanding the course (since clearly, even the basic info in the intro was beyond your understanding)." + }, + { + "review": "you are READING the slide nicely.", + "response": "Incorrect. The slides provide a summary of the spoken audio, like all courses on this site, all other video-based courses, and all presentations around the world. I'm amused that you would act \"surprised\" by such a normal occurrence... The slides are not being \"read\", and anyone taking the course can confirm this fact readily, so this comment is both inaccurate and misleading to potential students." + }, + { + "review": "There are some good topics explained, but lots of tutorials are just off topic (not about NLP), but various attempts from the instructor the explain to others why they're not able to understand stuff.", + "response": "You just have to remember that the course is not customized for you, it's for everyone. The \"FAQ\" section (meaning \"frequently asked questions\") answers questions other students are asking. It's unkind to suggest that I shouldn't answer questions from your fellow students." + }, + { + "review": "It doesn’t make sense to have to make an account outside of Udemy to then have to read an article that gives an analogy about \"burgers\" just to then inform you that you have to wait 31 days to view the material. Just upload the video like every other instructor and inform us that you have other material. Don’t force us to the material.", + "response": "Incorrect. You don't have to \"make an account outside of Udemy\" to take this course. That is for a different VERSION of the course for students who want to go above and beyond and learn more exciting material, in case they want to learn stuff OUTSIDE the course description [which I'm sure you've diligently read ;)]." + }, + { + "review": "I feel pretty lost, I feel like showing an example of what we're trying to achieve even thought it comes way later in the course would show how the individual parts of the course will play into it.", + "response": "This is what happens when you don't follow the instructions, like meeting the prerequisites or using the Q&A." + }, + { + "review": "Teacher is good at explaining concepts,albeit he has some language problems.", + "response": "English is my only language, but based on your comment alone, it is clear that the language problems may be on your end. I suggest improving in this area to better understand the course, thanks!" + }, + { + "review": "Honestly !! this is highly insufficient material. When we open the books of Machine Learning, we are lost in understanding the mathematical notations. However, this course is teaching Integration way below the levels of Class 12. My comment - It needs improvement", + "response": "Please make sure you read the course description so you understand the purpose of this course. For example, hard integration problems would not serve that purpose." + }, + { + "review": "The course has no depth where the instructor explains an intuition and runs off. The exercises given have no solutions and you have to do it either yourself or you suck and they can't help you! I wouldn't recommend it. Feels more like a refresher course than a course for someone to learn from scratch.", + "response": "> The course has no depth where the instructor explains an intuition and runs off.\n\nIncorrect. Every concept lecture is followed by Python code.\n\n> The exercises given have no solutions\n\nIncorrect. Exercise solutions are in the videos... please pay attention to improve your understanding, thanks." + }, + { + "review": "I feel helped by this course, but I am a bit confused about understanding the Markov model, but in other materials I can smoothly. Thank you for making this class, I hope you are always healthy.", + "response": "Please note that the sections are clearly marked beginner, intermediate, or advanced. This is so that you can stick to your level without being confused about material that is too advanced for you." + }, + { + "review": "Thank you for your prompt response. Let's be frank. I'm no novice to this topic, and I took your course hoping to get a fresh perspective. However, I was met with content that seemed hastily put together and felt more like a reference guide rather than a comprehensive educational course. I've previously enrolled in some of your courses, which were of higher quality. My feedback is based on a comparison with your own past materials. I hope you'll take this as an opportunity to review and enhance the course content for the benefit of future students.", + "response": "All algorithms are derived from scratch and based on the prerequisites, it is not a \"reference guide\". It seems strange that someone who is \"no novice to this topic\" would get those confused..." + }, + { + "review": "Too much talking, less content till now", + "response": "It's a video course, I'm not sure how one would avoid talking..." + }, + { + "review": "While this course has multiple sections on how LP believes you should be learning. That time could have been spent reinforcing some of the more difficult concepts with additional examples.", + "response": "This is a common misunderstanding of the appendix/FAQ. It's not \"That time could have been spent reinforcing some of the more difficult concepts with additional examples\". This content doesn't displace any other content." + }, + { + "review": "Therotical only.....No Example......just copy from book and paste it.......read it.....No Implementation...................", + "response": "Incorrect. Everything has been implemented from scratch. Please pay attention to improve your understanding, and please watch the FAQ lecture \"Beginner's Coding Tips\", thanks!" + }, + { + "review": "I haven't proceeded in the course yet but I wouldn't say I liked the instructor's stance on students asking dumb questions.", + "response": "That seems very weird. In the \"how to succeed\" lecture it clearly states that I encourage any and all questions. Why would you disagree with that?" + }, + { + "review": "If you hang out on YouTube probably you find the same information in the same time", + "response": "You can say that about any subject. The real question is, if it's so easy, then why haven't you done so? ;)" + }, + { + "review": "Generally useful but structure of content and direction of course is not always clear. We jump backwards and forwards between methods more than I would like.", + "response": "Each section is devoted to a different \"method\", there's no jumping \"back and forth\" between them..." + }, + { + "review": "I do not think its advanced stuff at all, nevertheless its good.", + "response": "Read the course description to learn what this course is about. In addition, please see the FAQ, which answers questions such as whether this course is for beginners or experts." + }, + { + "review": "There is constant talk about not having to understand the theory but it seems like the maths goes hand in hand with the models so not sure if it is feasible to just learn the code without understanding why you do certain things", + "response": "Because you're not implementing any of that math yourself, only using high level libraries. Please pay more attention to improve your understanding, thanks!" + }, + { + "review": "not get any technical knowledge yet", + "response": "Why not read the course description so that you understand what this course is about?" + }, + { + "review": "I came here to learn industry level but it does not meet my expectations. this course suits you well for beginners because you can learn all the math and coding from scratch.", + "response": "You simply have an incorrect understanding about what constitutes \"industry level\" (hint: you are not at this level)." + }, + { + "review": "there could be hands-on session rather than pre written code . This would help in understanding the logic better.", + "response": "I've instructed you to code by yourself, not to peek at my prewritten solutions. Therefore, you have simply not followed the instructions. You claim to want to be \"hands-on\", yet you haven't even done the hands-on work I've prescribed." + }, + { + "review": "If you are new to AI, don't take this course. Find something else to start with. Most of what I got from this course is exposure to possibilities with recommender systems. It is not the most organized course either", + "response": "Why should you be new to AI? You should meet the prerequisites, as instructed. Furthermore, it's not \"exposure to possibilities\", we are implementing many concrete algorithms. If you're having trouble understanding how the course is organized, it's one algorithm per section. I suggest simply paying more attention. Thanks!" + }, + { + "review": "sometimes a little superficial", + "response": "Thanks for your feedback. Please make sure to READ the course description so you understand what this course is about before taking it, thanks!" + }, + { + "review": "I am an industry data scientist with an academic background in Machine learning, I have done several deep learning projects in my school years, I am taking this as a refresher. But equations don't have an explanation of variables, and what they stand for, the instructor repetitively mentions that if you don't know any equations you are not ready for this course but no one knows an equation, how it is derived, and what all the greek symbols mean right off the bat especially if you are away from macadamia for a few years. If you add additional resources(eg: citation as you should!) we can read and understand your variables, also many textbooks use different notations, so you need to make your description clear. Also, I don't like the tone and rudeness of the instructor. He sounds like a mad professor, this is a recorded video, so take away the anger", + "response": "> But equations don't have an explanation of variables, and what they stand for\n\nThere is literally a lecture titled \"What do all these symbols and letters mean?\", which is actually a review of previously taught explanations (in other words, variables have been defined multiple times in many cases). Perhaps the problem is that you're simply not paying attention...\n\nAt the very least, thank you for making it obvious to the readers here that your claims are unfounded.\n\n> Also, I don't like the tone and rudeness of the instructor.\n\nYes, I know some students don't like being corrected (as above) and construe all corrections as rude because it's impossible for them to be wrong. But how can a teacher do his job if every correction is interpreted as rude?" + }, + { + "review": "They can't send me slide for this course.", + "response": "Incorrect. Slides are available upon request. Simply use the Q&A as instructed in the how to succeed lecture." + }, + { + "review": "The instructor is poor. Read their responses to other negative reviews. Really off-putting. Constantly stating how people are INCORRECT showing the instructor clearly has no ability to take constructive criticism. If only the instructor could A/B test their own responses. Honestly thought it was a good-ish course. The instructor earned a 1-star here.", + "response": "No, \"incorrect\" is used to denote factually wrong statements. It appears you are too emotional, focusing on your feelings (you're offended that I've corrected others) instead of the facts." + }, + { + "review": "Please respect yourself, you must be ashamed of yourself because of this. Peyser", + "response": "Thanks for your feedback! It'd be great if you could provide specifics regarding what you didn't like about the course..." + }, + { + "review": "Mentor is providing slides for video and he is also fooling student to stay 31 on Udemy but after 31 days I am not finding any slides and note from instructor side.", + "response": "Incorrect. Comment speaks for itself really." + }, + { + "review": "This course kind of breezes over the topics, there are colabs used in the videos that we do not have access to and Section 4 is irrelevant to the course, I would rather see my on the topic and learn something than how to install tools that I already know how to do. Section 4 should actually be on his youtube site. There should also be more links to the tools he speaks of or uses, you have to stop the video and actually go google the tools and search for them. I am still trying to find ffmpegexamples.ipynb that is used for a whole segment of the training but there is no access to. Good course but needs a lot of fine-tuning to be better. I hope to see more added to create better content.", + "response": "> there are colabs used in the videos that we do not have access to\n\nIncorrect. Lecture 4 is called \"COURSE RESOURCES\". Any guesses about what this is for?\n\n> Section 4 is irrelevant to the course\n\nInteresting, who should decide what's relevant to the course? Instructor (who understands the course content) or student (who does not)?\n\n> I would rather see my on the topic\n\nThis is not even a coherent sentence.\n\n> There should also be more links to the tools he speaks of or uses, you have to stop the video and actually go google the tools and search for them\n\nAgain, no you do not. This is what happens when you don't pay attention.\n\n> I am still trying to find ffmpegexamples.ipynb\n\nIf you paid attention, you would have already found it.\n\n> Good course but needs a lot of fine-tuning to be better. I hope to see more added to create better content.\n\nNo, you just need to follow the instructions and use the Q&A to fix your misunderstandings. I don't see how it could be any simpler." + } +] diff --git a/openai/robots_playing_soccer.jpeg b/openai/robots_playing_soccer.jpeg new file mode 100644 index 00000000..547761ae Binary files /dev/null and b/openai/robots_playing_soccer.jpeg differ diff --git a/openai/webdesign.jpg b/openai/webdesign.jpg new file mode 100644 index 00000000..ecce702e Binary files /dev/null and b/openai/webdesign.jpg differ diff --git a/probability/WHERE ARE THE NOTEBOOKS.txt b/probability/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/probability/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/probability/extra_reading.txt b/probability/extra_reading.txt new file mode 100644 index 00000000..e2df1a0d --- /dev/null +++ b/probability/extra_reading.txt @@ -0,0 +1,2 @@ +Multivariate Change of Variables +https://math.libretexts.org/Bookshelves/Calculus/Book%3A_Active_Calculus_(Boelkins_et_al.)/11%3A_Multiple_Integrals/11.09%3A_Change_of_Variables \ No newline at end of file diff --git a/prophet/extra_reading.txt b/prophet/extra_reading.txt new file mode 100644 index 00000000..1e2ea58c --- /dev/null +++ b/prophet/extra_reading.txt @@ -0,0 +1,2 @@ +Forecasting at Scale (Facebook Prophet) +https://peerj.com/preprints/3190.pdf \ No newline at end of file diff --git a/pytorch/WHERE ARE THE NOTEBOOKS.txt b/pytorch/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/pytorch/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/pytorch/exercises.txt b/pytorch/exercises.txt index aa364191..6fdee299 100644 --- a/pytorch/exercises.txt +++ b/pytorch/exercises.txt @@ -13,7 +13,7 @@ https://lazyprogrammer.me/course_files/exercises/ecoli.csv CNN https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge -https://lazyprogrammer.me/course_files/fer2013.csv +https://archive.org/download/fer2013_202311/fer2013.csv RNN Find your own stock price dataset! diff --git a/pytorch/extra_reading.txt b/pytorch/extra_reading.txt index e7bdc2ea..7fccf01f 100644 --- a/pytorch/extra_reading.txt +++ b/pytorch/extra_reading.txt @@ -15,7 +15,7 @@ Implementing Dropout https://deeplearningcourses.com/c/data-science-deep-learning-in-theano-tensorflow/ Convolution arithmetic tutorial -http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html +https://theano-pymc.readthedocs.io/en/latest/tutorial/conv_arithmetic.html On the Practical Computational Power of Finite Precision RNNs for Language Recognition https://arxiv.org/abs/1805.04908 diff --git a/recommenders/autorec.py b/recommenders/autorec.py index 02ff05b9..fa0bd415 100644 --- a/recommenders/autorec.py +++ b/recommenders/autorec.py @@ -102,7 +102,7 @@ def test_generator(A, M, A_test, M_test): ) -r = model.fit_generator( +r = model.fit( generator(A, mask), validation_data=test_generator(A_copy, mask_copy, A_test_copy, mask_test_copy), epochs=epochs, diff --git a/recommenders/extra_reading.txt b/recommenders/extra_reading.txt index 21d09a4b..510410cd 100644 --- a/recommenders/extra_reading.txt +++ b/recommenders/extra_reading.txt @@ -56,4 +56,7 @@ AutoRec: Autoencoders Meet Collaborative Filtering http://users.cecs.anu.edu.au/~u5098633/papers/www15.pdf Collaborative Filtering for Implicit Feedback Datasets -http://yifanhu.net/PUB/cf.pdf \ No newline at end of file +http://yifanhu.net/PUB/cf.pdf + +Neural Collaborative Filtering +https://arxiv.org/abs/1708.05031 \ No newline at end of file diff --git a/rl/cartpole.py b/rl/cartpole.py index 2ef157b5..abb1b617 100644 --- a/rl/cartpole.py +++ b/rl/cartpole.py @@ -29,14 +29,15 @@ def epsilon_greedy(model, s, eps=0.1): def gather_samples(env, n_episodes=10000): samples = [] for _ in range(n_episodes): - s = env.reset() + s, info = env.reset() done = False - while not done: + truncated = False + while not (done or truncated): a = env.action_space.sample() sa = np.concatenate((s, [a])) samples.append(sa) - s, r, done, info = env.step(a) + s, r, done, truncated, info = env.step(a) return samples @@ -70,11 +71,12 @@ def test_agent(model, env, n_episodes=20): reward_per_episode = np.zeros(n_episodes) for it in range(n_episodes): done = False + truncated = False episode_reward = 0 - s = env.reset() - while not done: + s, info = env.reset() + while not (done or truncated): a = epsilon_greedy(model, s, eps=0) - s, r, done, info = env.step(a) + s, r, done, truncated, info = env.step(a) episode_reward += r reward_per_episode[it] = episode_reward return np.mean(reward_per_episode) @@ -82,19 +84,19 @@ def test_agent(model, env, n_episodes=20): def watch_agent(model, env, eps): done = False + truncated = False episode_reward = 0 - s = env.reset() - while not done: + s, info = env.reset() + while not (done or truncated): a = epsilon_greedy(model, s, eps=eps) - s, r, done, info = env.step(a) - env.render() + s, r, done, truncated, info = env.step(a) episode_reward += r print("Episode reward:", episode_reward) if __name__ == '__main__': # instantiate environment - env = gym.make("CartPole-v0") + env = gym.make("CartPole-v1", render_mode="rgb_array") model = Model(env) reward_per_episode = [] @@ -105,12 +107,13 @@ def watch_agent(model, env, eps): # repeat until convergence n_episodes = 1500 for it in range(n_episodes): - s = env.reset() + s, info = env.reset() episode_reward = 0 done = False - while not done: + truncated = False + while not (done or truncated): a = epsilon_greedy(model, s) - s2, r, done, info = env.step(a) + s2, r, done, truncated, info = env.step(a) # get the target if done: @@ -149,5 +152,6 @@ def watch_agent(model, env, eps): plt.show() # watch trained agent + env = gym.make("CartPole-v1", render_mode="human") watch_agent(model, env, eps=0) diff --git a/rl/cartpole_gym0.19.py b/rl/cartpole_gym0.19.py new file mode 100644 index 00000000..2ef157b5 --- /dev/null +++ b/rl/cartpole_gym0.19.py @@ -0,0 +1,153 @@ +# https://deeplearningcourses.com/c/artificial-intelligence-reinforcement-learning-in-python +# https://www.udemy.com/artificial-intelligence-reinforcement-learning-in-python +from __future__ import print_function, division +from builtins import range +# Note: you may need to update your version of future +# sudo pip install -U future + +import gym +import numpy as np +import matplotlib.pyplot as plt +from sklearn.kernel_approximation import RBFSampler + + +GAMMA = 0.99 +ALPHA = 0.1 + + +def epsilon_greedy(model, s, eps=0.1): + # we'll use epsilon-soft to ensure all states are visited + # what happens if you don't do this? i.e. eps=0 + p = np.random.random() + if p < (1 - eps): + values = model.predict_all_actions(s) + return np.argmax(values) + else: + return model.env.action_space.sample() + + +def gather_samples(env, n_episodes=10000): + samples = [] + for _ in range(n_episodes): + s = env.reset() + done = False + while not done: + a = env.action_space.sample() + sa = np.concatenate((s, [a])) + samples.append(sa) + + s, r, done, info = env.step(a) + return samples + + +class Model: + def __init__(self, env): + # fit the featurizer to data + self.env = env + samples = gather_samples(env) + self.featurizer = RBFSampler() + self.featurizer.fit(samples) + dims = self.featurizer.n_components + + # initialize linear model weights + self.w = np.zeros(dims) + + def predict(self, s, a): + sa = np.concatenate((s, [a])) + x = self.featurizer.transform([sa])[0] + return x @ self.w + + def predict_all_actions(self, s): + return [self.predict(s, a) for a in range(self.env.action_space.n)] + + def grad(self, s, a): + sa = np.concatenate((s, [a])) + x = self.featurizer.transform([sa])[0] + return x + + +def test_agent(model, env, n_episodes=20): + reward_per_episode = np.zeros(n_episodes) + for it in range(n_episodes): + done = False + episode_reward = 0 + s = env.reset() + while not done: + a = epsilon_greedy(model, s, eps=0) + s, r, done, info = env.step(a) + episode_reward += r + reward_per_episode[it] = episode_reward + return np.mean(reward_per_episode) + + +def watch_agent(model, env, eps): + done = False + episode_reward = 0 + s = env.reset() + while not done: + a = epsilon_greedy(model, s, eps=eps) + s, r, done, info = env.step(a) + env.render() + episode_reward += r + print("Episode reward:", episode_reward) + + +if __name__ == '__main__': + # instantiate environment + env = gym.make("CartPole-v0") + + model = Model(env) + reward_per_episode = [] + + # watch untrained agent + watch_agent(model, env, eps=0) + + # repeat until convergence + n_episodes = 1500 + for it in range(n_episodes): + s = env.reset() + episode_reward = 0 + done = False + while not done: + a = epsilon_greedy(model, s) + s2, r, done, info = env.step(a) + + # get the target + if done: + target = r + else: + values = model.predict_all_actions(s2) + target = r + GAMMA * np.max(values) + + # update the model + g = model.grad(s, a) + err = target - model.predict(s, a) + model.w += ALPHA * err * g + + # accumulate reward + episode_reward += r + + # update state + s = s2 + + if (it + 1) % 50 == 0: + print(f"Episode: {it + 1}, Reward: {episode_reward}") + + # early exit + if it > 20 and np.mean(reward_per_episode[-20:]) == 200: + print("Early exit") + break + + reward_per_episode.append(episode_reward) + + # test trained agent + test_reward = test_agent(model, env) + print(f"Average test reward: {test_reward}") + + plt.plot(reward_per_episode) + plt.title("Reward per episode") + plt.show() + + # watch trained agent + watch_agent(model, env, eps=0) + diff --git a/rl/extra_reading.txt b/rl/extra_reading.txt index 64dd9812..fac79d64 100644 --- a/rl/extra_reading.txt +++ b/rl/extra_reading.txt @@ -1,6 +1,9 @@ Finite-time Analysis of the Multiarmed Bandit Problem https://homes.di.unimi.it/cesa-bianchi/Pubblicazioni/ml-02.pdf +A Nice Lecture for Students Who Claim "RL Doesn't Use Math" +https://www.youtube.com/watch?v=dhEF5pfYmvc + Hacking Google reCAPTCHA v3 using Reinforcement Learning https://arxiv.org/pdf/1903.01003.pdf diff --git a/rl2/a3c/main.py b/rl2/a3c/main.py index 0e7f88bf..a902ff03 100644 --- a/rl2/a3c/main.py +++ b/rl2/a3c/main.py @@ -13,6 +13,14 @@ from worker import Worker +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + + ENV_NAME = "Breakout-v0" MAX_GLOBAL_STEPS = 5e6 STEPS_PER_UPDATE = 5 diff --git a/rl2/atari/dqn_tf.py b/rl2/atari/dqn_tf.py old mode 100644 new mode 100755 index 34c1ab16..e37394d1 --- a/rl2/atari/dqn_tf.py +++ b/rl2/atari/dqn_tf.py @@ -19,7 +19,12 @@ +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") ##### testing only # MAX_EXPERIENCES = 10000 @@ -141,7 +146,11 @@ def get_minibatch(self): self.states[i] = self._get_state(idx - 1) self.new_states[i] = self._get_state(idx) - return np.transpose(self.states, axes=(0, 2, 3, 1)), self.actions[self.indices], self.rewards[self.indices], np.transpose(self.new_states, axes=(0, 2, 3, 1)), self.terminal_flags[self.indices] + return np.transpose(self.states, axes=(0, 2, 3, 1)), \ + self.actions[self.indices], \ + self.rewards[self.indices], \ + np.transpose(self.new_states, axes=(0, 2, 3, 1)), \ + self.terminal_flags[self.indices] class DQN: diff --git a/rl2/atari/dqn_theano.py b/rl2/atari/dqn_theano.py old mode 100644 new mode 100755 index e0114b59..0ad3b36a --- a/rl2/atari/dqn_theano.py +++ b/rl2/atari/dqn_theano.py @@ -140,7 +140,11 @@ def get_minibatch(self): self.states[i] = self._get_state(idx - 1) self.new_states[i] = self._get_state(idx) - return self.states, self.actions[self.indices], self.rewards[self.indices], self.new_states, self.terminal_flags[self.indices] + return self.states, \ + self.actions[self.indices], \ + self.rewards[self.indices], \ + self.new_states, \ + self.terminal_flags[self.indices] def init_filter(shape): diff --git a/rl2/cartpole/dqn_tf.py b/rl2/cartpole/dqn_tf.py index e397acd6..133772df 100644 --- a/rl2/cartpole/dqn_tf.py +++ b/rl2/cartpole/dqn_tf.py @@ -15,6 +15,13 @@ from datetime import datetime from q_learning_bins import plot_running_avg +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + # global counter global_iters = 0 diff --git a/rl2/cartpole/dqn_theano.py b/rl2/cartpole/dqn_theano.py index 08dd2ded..18e6844c 100644 --- a/rl2/cartpole/dqn_theano.py +++ b/rl2/cartpole/dqn_theano.py @@ -16,6 +16,10 @@ from datetime import datetime from q_learning_bins import plot_running_avg +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + # global counter global_iters = 0 diff --git a/rl2/cartpole/pg_tf.py b/rl2/cartpole/pg_tf.py index d5021eb7..40122df0 100644 --- a/rl2/cartpole/pg_tf.py +++ b/rl2/cartpole/pg_tf.py @@ -16,6 +16,13 @@ from datetime import datetime from q_learning_bins import plot_running_avg +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + # so you can test different architectures class HiddenLayer: diff --git a/rl2/cartpole/pg_theano.py b/rl2/cartpole/pg_theano.py index 99ac7aec..16979d5f 100644 --- a/rl2/cartpole/pg_theano.py +++ b/rl2/cartpole/pg_theano.py @@ -17,6 +17,10 @@ from datetime import datetime from q_learning_bins import plot_running_avg +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + # so you can test different architectures class HiddenLayer: diff --git a/rl2/cartpole/q_learning.py b/rl2/cartpole/q_learning.py index d02fbc05..3e7cc4a5 100644 --- a/rl2/cartpole/q_learning.py +++ b/rl2/cartpole/q_learning.py @@ -20,6 +20,10 @@ from sklearn.kernel_approximation import RBFSampler from q_learning_bins import plot_running_avg +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + class SGDRegressor: def __init__(self, D): diff --git a/rl2/cartpole/q_learning_bins.py b/rl2/cartpole/q_learning_bins.py index 3d3ed041..198ceb2a 100644 --- a/rl2/cartpole/q_learning_bins.py +++ b/rl2/cartpole/q_learning_bins.py @@ -15,6 +15,10 @@ from gym import wrappers from datetime import datetime +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + # turns list of integers into an int # Ex. diff --git a/rl2/cartpole/random_search.py b/rl2/cartpole/random_search.py index 77ea36d6..985bcfda 100644 --- a/rl2/cartpole/random_search.py +++ b/rl2/cartpole/random_search.py @@ -9,6 +9,10 @@ import numpy as np import matplotlib.pyplot as plt +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + def get_action(s, w): return 1 if s.dot(w) > 0 else 0 diff --git a/rl2/cartpole/save_a_video.py b/rl2/cartpole/save_a_video.py index 31690c29..e7128fc9 100644 --- a/rl2/cartpole/save_a_video.py +++ b/rl2/cartpole/save_a_video.py @@ -10,6 +10,11 @@ import numpy as np import matplotlib.pyplot as plt +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + + def get_action(s, w): return 1 if s.dot(w) > 0 else 0 @@ -63,5 +68,5 @@ def random_search(env): plt.show() # play a final set of episodes - env = wrappers.Monitor(env, 'my_awesome_dir') + env = wrappers.RecordVideo(env, 'my_awesome_dir') print("***Final run with final weights***:", play_one_episode(env, params)) diff --git a/rl2/cartpole/td_lambda.py b/rl2/cartpole/td_lambda.py index ff19f627..ba9883bc 100644 --- a/rl2/cartpole/td_lambda.py +++ b/rl2/cartpole/td_lambda.py @@ -15,6 +15,11 @@ from q_learning import FeatureTransformer from q_learning_bins import plot_running_avg +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + + class SGDRegressor: def __init__(self, D): diff --git a/rl2/cartpole/tf_warmup.py b/rl2/cartpole/tf_warmup.py index 877cd54a..1cc2efee 100644 --- a/rl2/cartpole/tf_warmup.py +++ b/rl2/cartpole/tf_warmup.py @@ -7,6 +7,9 @@ import tensorflow as tf import q_learning +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + class SGDRegressor: def __init__(self, D): diff --git a/rl2/gym_tutorial.py b/rl2/gym_tutorial.py index 7a2d7dbb..ace01452 100644 --- a/rl2/gym_tutorial.py +++ b/rl2/gym_tutorial.py @@ -6,6 +6,11 @@ # Environment page: # https://gym.openai.com/envs/CartPole-v0 +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + + # get the environment env = gym.make('CartPole-v0') diff --git a/rl2/mountaincar/n_step.py b/rl2/mountaincar/n_step.py index 5ef967ff..628fdbcf 100644 --- a/rl2/mountaincar/n_step.py +++ b/rl2/mountaincar/n_step.py @@ -54,7 +54,7 @@ def predict(self, X): # returns a list of states_and_rewards, and the total reward def play_one(model, eps, gamma, n=5): - observation = env.reset() + observation = env.reset()[0] done = False totalreward = 0 rewards = [] @@ -73,7 +73,7 @@ def play_one(model, eps, gamma, n=5): actions.append(action) prev_observation = observation - observation, reward, done, info = env.step(action) + observation, reward, done, truncated, info = env.step(action) rewards.append(reward) @@ -81,7 +81,10 @@ def play_one(model, eps, gamma, n=5): if len(rewards) >= n: # return_up_to_prediction = calculate_return_before_prediction(rewards, gamma) return_up_to_prediction = multiplier.dot(rewards[-n:]) - G = return_up_to_prediction + (gamma**n)*np.max(model.predict(observation)[0]) + action_values = model.predict(observation)[0] + # print("action_values.shape:", action_values.shape) + G = return_up_to_prediction + (gamma**n)*np.max(action_values) + # print("G:", G) model.update(states[-n], actions[-n], G) # if len(rewards) > n: diff --git a/rl2/mountaincar/pg_tf.py b/rl2/mountaincar/pg_tf.py old mode 100644 new mode 100755 index b8c8ef59..fe04b416 --- a/rl2/mountaincar/pg_tf.py +++ b/rl2/mountaincar/pg_tf.py @@ -15,6 +15,13 @@ from datetime import datetime from q_learning import plot_running_avg, FeatureTransformer, plot_cost_to_go +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + # so you can test different architectures class HiddenLayer: @@ -177,8 +184,12 @@ def play_one_td(env, pmodel, vmodel, gamma): totalreward += reward # update the models - V_next = vmodel.predict(observation) - G = reward + gamma*V_next + if done: + G = reward + else: + V_next = vmodel.predict(observation) + G = reward + gamma*V_next + advantage = G - vmodel.predict(prev_observation) pmodel.partial_fit(prev_observation, action, advantage) vmodel.partial_fit(prev_observation, G) diff --git a/rl2/mountaincar/pg_tf_random.py b/rl2/mountaincar/pg_tf_random.py index bb0d2a11..e46b7b25 100644 --- a/rl2/mountaincar/pg_tf_random.py +++ b/rl2/mountaincar/pg_tf_random.py @@ -15,6 +15,13 @@ from datetime import datetime from q_learning import plot_running_avg, FeatureTransformer +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + # so you can test different architectures class HiddenLayer: diff --git a/rl2/mountaincar/pg_theano.py b/rl2/mountaincar/pg_theano.py old mode 100644 new mode 100755 index cf1c8f01..669fc416 --- a/rl2/mountaincar/pg_theano.py +++ b/rl2/mountaincar/pg_theano.py @@ -208,7 +208,7 @@ def predict(self, X): return self.predict_op(X) -def play_one_td(env, pmodel, vmodel, gamma, train=True): +def play_one_td(env, pmodel, vmodel, gamma): observation = env.reset() done = False totalreward = 0 @@ -224,12 +224,15 @@ def play_one_td(env, pmodel, vmodel, gamma, train=True): totalreward += reward # update the models - if train: + if done: + G = reward + else: V_next = vmodel.predict(observation) G = reward + gamma*V_next - advantage = G - vmodel.predict(prev_observation) - pmodel.partial_fit(prev_observation, action, advantage) - vmodel.partial_fit(prev_observation, G) + + advantage = G - vmodel.predict(prev_observation) + pmodel.partial_fit(prev_observation, action, advantage) + vmodel.partial_fit(prev_observation, G) iters += 1 diff --git a/rl2/mountaincar/pg_theano_random.py b/rl2/mountaincar/pg_theano_random.py index 9ac07b16..c95c5971 100644 --- a/rl2/mountaincar/pg_theano_random.py +++ b/rl2/mountaincar/pg_theano_random.py @@ -16,6 +16,10 @@ from datetime import datetime from q_learning import plot_running_avg, FeatureTransformer +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + # so you can test different architectures diff --git a/rl2/mountaincar/q_learning.py b/rl2/mountaincar/q_learning.py old mode 100644 new mode 100755 index 1d4be4f2..129d67e0 --- a/rl2/mountaincar/q_learning.py +++ b/rl2/mountaincar/q_learning.py @@ -70,7 +70,7 @@ def __init__(self, env, feature_transformer, learning_rate): self.feature_transformer = feature_transformer for i in range(env.action_space.n): model = SGDRegressor(learning_rate=learning_rate) - model.partial_fit(feature_transformer.transform( [env.reset()] ), [0]) + model.partial_fit(feature_transformer.transform( [env.reset()[0]] ), [0]) self.models.append(model) def predict(self, s): @@ -99,19 +99,23 @@ def sample_action(self, s, eps): # returns a list of states_and_rewards, and the total reward def play_one(model, env, eps, gamma): - observation = env.reset() + observation = env.reset()[0] done = False totalreward = 0 iters = 0 while not done and iters < 10000: action = model.sample_action(observation, eps) prev_observation = observation - observation, reward, done, info = env.step(action) + observation, reward, done, truncated, info = env.step(action) # update the model - next = model.predict(observation) - # assert(next.shape == (1, env.action_space.n)) - G = reward + gamma*np.max(next[0]) + if done: + G = reward + else: + Qnext = model.predict(observation) + # assert(next.shape == (1, env.action_space.n)) + G = reward + gamma*np.max(Qnext[0]) + model.update(prev_observation, action, G) totalreward += reward @@ -165,14 +169,14 @@ def main(show_plots=True): N = 300 totalrewards = np.empty(N) for n in range(N): - # eps = 1.0/(0.1*n+1) - eps = 0.1*(0.97**n) + eps = 1.0/(0.1*n+1) + # eps = 0.1*(0.97**n) if n == 199: print("eps:", eps) # eps = 1.0/np.sqrt(n+1) totalreward = play_one(model, env, eps, gamma) totalrewards[n] = totalreward - if (n + 1) % 100 == 0: + if (n + 1) % 10 == 0: print("episode:", n, "total reward:", totalreward) print("avg reward for last 100 episodes:", totalrewards[-100:].mean()) print("total steps:", -totalrewards.sum()) diff --git a/rl2/mountaincar/td_lambda.py b/rl2/mountaincar/td_lambda.py old mode 100644 new mode 100755 index 4d4f292d..3d7dd8ac --- a/rl2/mountaincar/td_lambda.py +++ b/rl2/mountaincar/td_lambda.py @@ -23,6 +23,10 @@ # code we already wrote from q_learning import plot_cost_to_go, FeatureTransformer, plot_running_avg +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + class BaseModel: def __init__(self, D): @@ -83,9 +87,9 @@ def play_one(model, env, eps, gamma, lambda_): observation, reward, done, info = env.step(action) # update the model - next = model.predict(observation) - assert(next.shape == (1, env.action_space.n)) - G = reward + gamma*np.max(next[0]) + Qnext = model.predict(observation) + assert(Qnext.shape == (1, env.action_space.n)) + G = reward + gamma*np.max(Qnext[0]) model.update(prev_observation, action, G, gamma, lambda_) totalreward += reward diff --git a/rl2v2/extra_reading.txt b/rl2v2/extra_reading.txt new file mode 100644 index 00000000..b1b113f2 --- /dev/null +++ b/rl2v2/extra_reading.txt @@ -0,0 +1,8 @@ +Gymnasium Library +https://gymnasium.farama.org/ + +Stable Baselines 3 +https://github.com/DLR-RM/stable-baselines3 + +Reinforcement Learning Prerequisites +https://deeplearningcourses.com/c/artificial-intelligence-reinforcement-learning-in-python \ No newline at end of file diff --git a/rl3/a2c/a2c.py b/rl3/a2c/a2c.py index 3b7d3268..ce1667b1 100644 --- a/rl3/a2c/a2c.py +++ b/rl3/a2c/a2c.py @@ -5,6 +5,9 @@ import tensorflow as tf import os +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + def set_global_seeds(i): tf.set_random_seed(i) diff --git a/rl3/a2c/main.py b/rl3/a2c/main.py index 3bf85105..b42c86d9 100644 --- a/rl3/a2c/main.py +++ b/rl3/a2c/main.py @@ -11,6 +11,10 @@ import argparse import logging +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # Mute missing instructions errors MODEL_PATH = 'models' diff --git a/rl3/ddpg.py b/rl3/ddpg.py index 3eb80d1c..3913cedd 100644 --- a/rl3/ddpg.py +++ b/rl3/ddpg.py @@ -5,6 +5,13 @@ import matplotlib.pyplot as plt from datetime import datetime +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + +if tf.__version__.startswith('2'): + exit("Please install Tensorflow 1.x") + ### avoid crashing on Mac # doesn't seem to work diff --git a/rl3/es_mujoco.py b/rl3/es_mujoco.py index ce43f983..3ef4ffd9 100644 --- a/rl3/es_mujoco.py +++ b/rl3/es_mujoco.py @@ -10,6 +10,11 @@ import gym import sys +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + + # environment ENV_NAME = 'HalfCheetah-v2' diff --git a/rl3/gym_review.py b/rl3/gym_review.py index 26733a58..3be2ac98 100644 --- a/rl3/gym_review.py +++ b/rl3/gym_review.py @@ -3,6 +3,11 @@ import numpy as np import matplotlib.pyplot as plt +gym_minor_version = int(gym.__version__.split('.')[1]) +if gym_minor_version >= 19: + exit("Please install OpenAI Gym 0.19.0 or earlier") + + def get_action(s, w): return 1 if s.dot(w) > 0 else 0 diff --git a/rl3v2/extra_reading.txt b/rl3v2/extra_reading.txt new file mode 100644 index 00000000..cdff9892 --- /dev/null +++ b/rl3v2/extra_reading.txt @@ -0,0 +1,23 @@ +=== PART 1 === + +ES (Evolution Strategies) +"Evolution Strategies as a Scalable Alternative to Reinforcement Learning" +https://arxiv.org/abs/1703.03864 + +Trust Region Evolution Strategies +https://www.microsoft.com/en-us/research/uploads/prod/2018/11/trust-region-evolution-strategies.pdf + +The CMA Evolution Strategy: A Tutorial +https://arxiv.org/pdf/1604.00772 + +Simple random search provides a competitive approach to reinforcement learning (Augmented Random Search) +https://arxiv.org/abs/1803.07055 + +=== PART 2 === + +DDPG (Deep Deterministic Policy Gradient) +"Continuous control with deep reinforcement learning" +https://arxiv.org/abs/1509.02971 + +Deterministic Policy Gradient Algorithms +http://proceedings.mlr.press/v32/silver14.pdf \ No newline at end of file diff --git a/rl3v2/visualize_es.py b/rl3v2/visualize_es.py new file mode 100644 index 00000000..e518c388 --- /dev/null +++ b/rl3v2/visualize_es.py @@ -0,0 +1,59 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Objective function to minimize (you can change this) +def f(x, y): + # return np.sin(x) + np.cos(y) + return -((x - 1)**2 + y**2) + +# Evolution Strategies optimizer (simple version) +def evolution_strategies( + f, bounds, pop_size=50, sigma=0.3, alpha=0.03, iterations=100 +): + dim = 2 + mu = np.random.uniform(bounds[0], bounds[1], size=dim) + + history = [] + + for gen in range(iterations): + # Sample noise + noise = np.random.randn(pop_size, dim) + population = mu + sigma * noise + fitness = np.array([f(x[0], x[1]) for x in population]) + + history.append((population.copy(), mu.copy())) + + # Normalize fitness for weighting + fitness_norm = (fitness - np.mean(fitness)) / (np.std(fitness) + 1e-8) + mu += alpha / (pop_size * sigma) * np.dot(noise.T, fitness_norm) + + return history + +# Visualization function +def visualize_es(history, bounds, f, resolution=100): + x = np.linspace(bounds[0], bounds[1], resolution) + y = np.linspace(bounds[0], bounds[1], resolution) + X, Y = np.meshgrid(x, y) + Z = f(X, Y) + + plt.figure(figsize=(8, 6)) + for i, (pop, mu) in enumerate(history): + plt.clf() + plt.contourf(X, Y, Z, levels=50, cmap='viridis') + plt.colorbar(label="f(x, y)") + plt.scatter(pop[:, 0], pop[:, 1], c='white', s=20, label='Population') + plt.scatter(mu[0], mu[1], c='red', s=80, label='Mean', edgecolors='black') + plt.title(f"Evolution Strategies - Step {i+1}") + plt.xlim(bounds[0], bounds[1]) + plt.ylim(bounds[0], bounds[1]) + plt.xlabel('x') + plt.ylabel('y') + plt.legend() + # plt.pause(0.1) + plt.waitforbuttonpress() + plt.show() + +# Run +bounds = (-5, 5) +history = evolution_strategies(f, bounds, iterations=80) +visualize_es(history, bounds, f) diff --git a/rl3v2/visualize_hill_climbing.py b/rl3v2/visualize_hill_climbing.py new file mode 100644 index 00000000..d640a20e --- /dev/null +++ b/rl3v2/visualize_hill_climbing.py @@ -0,0 +1,61 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Objective function to minimize (you can change this) +def f(x, y): + # return np.sin(x) + np.cos(y) + return -((x - 1)**2 + y**2) + +# Evolution Strategies optimizer (simple version) +def hill_climb( + f, bounds, pop_size=1, sigma=0.3, alpha=0.3, iterations=100 +): + dim = 2 + mu = np.random.uniform(bounds[0], bounds[1], size=dim) + + history = [] + best_f = f(mu) + + for gen in range(iterations): + # Sample noise + noise = np.random.randn(pop_size, dim) + population = mu + sigma * noise + fitness = np.array([f(x[0], x[1]) for x in population]) + + history.append((population.copy(), mu.copy())) + + # Update point if it's better + if fitness[0] > best_f: + best_f = fitness[0] + mu = population.flatten() + + return history + +# Visualization function +def visualize_es(history, bounds, f, resolution=100): + x = np.linspace(bounds[0], bounds[1], resolution) + y = np.linspace(bounds[0], bounds[1], resolution) + X, Y = np.meshgrid(x, y) + Z = f(X, Y) + + plt.figure(figsize=(8, 6)) + for i, (pop, mu) in enumerate(history): + plt.clf() + plt.contourf(X, Y, Z, levels=50, cmap='viridis') + plt.colorbar(label="f(x, y)") + plt.scatter(pop[:, 0], pop[:, 1], c='white', s=20, label='Population') + plt.scatter(mu[0], mu[1], c='red', s=80, label='Mean', edgecolors='black') + plt.title(f"Hill Climbing - Step {i+1}") + plt.xlim(bounds[0], bounds[1]) + plt.ylim(bounds[0], bounds[1]) + plt.xlabel('x') + plt.ylabel('y') + plt.legend() + # plt.pause(0.1) + plt.waitforbuttonpress() + plt.show() + +# Run +bounds = (-5, 5) +history = hill_climb(f, bounds, iterations=80) +visualize_es(history, bounds, f) diff --git a/rnn_class/WHERE ARE THE NOTEBOOKS.txt b/rnn_class/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/rnn_class/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/stats/extra_reading.txt b/stats/extra_reading.txt new file mode 100644 index 00000000..9dc9b858 --- /dev/null +++ b/stats/extra_reading.txt @@ -0,0 +1,2 @@ +The Unbiased Estimate of the Covariance Matrix +https://lazyprogrammer.me/covariance-matrix-divide-by-n-or-n-1/ \ No newline at end of file diff --git a/supervised_class2/rf_regression.py b/supervised_class2/rf_regression.py index 06ee72fb..ae31cef4 100644 --- a/supervised_class2/rf_regression.py +++ b/supervised_class2/rf_regression.py @@ -1,6 +1,7 @@ # https://deeplearningcourses.com/c/machine-learning-in-python-random-forest-adaboost # https://www.udemy.com/machine-learning-in-python-random-forest-adaboost # uses house dataset from https://archive.ics.uci.edu/ml/machine-learning-databases/housing/ +# Alternate data source: https://archive.org/download/housing_202405/housing.data # put all files in the folder ../large_files from __future__ import print_function, division from future.utils import iteritems diff --git a/tf2.0/WHERE ARE THE NOTEBOOKS.txt b/tf2.0/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/tf2.0/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/tf2.0/exercises.txt b/tf2.0/exercises.txt index aa364191..6fdee299 100644 --- a/tf2.0/exercises.txt +++ b/tf2.0/exercises.txt @@ -13,7 +13,7 @@ https://lazyprogrammer.me/course_files/exercises/ecoli.csv CNN https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge -https://lazyprogrammer.me/course_files/fer2013.csv +https://archive.org/download/fer2013_202311/fer2013.csv RNN Find your own stock price dataset! diff --git a/tf2.0/extra_reading.txt b/tf2.0/extra_reading.txt index 041ff992..a23d273c 100644 --- a/tf2.0/extra_reading.txt +++ b/tf2.0/extra_reading.txt @@ -12,7 +12,7 @@ Dropout: A Simple Way to Prevent Neural Networks from Overfitting https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf Convolution arithmetic tutorial -http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html +https://theano-pymc.readthedocs.io/en/latest/tutorial/conv_arithmetic.html On the Practical Computational Power of Finite Precision RNNs for Language Recognition https://arxiv.org/abs/1805.04908 @@ -27,4 +27,10 @@ Inceptionism: Going Deeper into Neural Networks https://ai.googleblog.com/2015/06/inceptionism-going-deeper-into-neural.html The Loss Surfaces of Multilayer Networks -https://arxiv.org/pdf/1412.0233.pdf \ No newline at end of file +https://arxiv.org/pdf/1412.0233.pdf + +Tensorflow Developer Certificate Installation Guide +https://www.tensorflow.org/static/extras/cert/Setting_Up_TF_Developer_Certificate_Exam.pdf + +Tensorflow Developer Certificate Candidate Handbook +https://www.tensorflow.org/extras/cert/TF_Certificate_Candidate_Handbook.pdf diff --git a/tf2.0/keras_trader.py b/tf2.0/keras_trader.py new file mode 100644 index 00000000..18545989 --- /dev/null +++ b/tf2.0/keras_trader.py @@ -0,0 +1,421 @@ +import numpy as np +import pandas as pd + +# must do this BEFORE importing keras +import os +os.environ["KERAS_BACKEND"] = "jax" + +from keras.models import Model +from keras.layers import Dense, Input +from keras.optimizers import Adam + +from datetime import datetime +import itertools +import argparse +import re +import pickle + +from sklearn.preprocessing import StandardScaler + + +import keras.backend as K +print("Using backend:", K.backend()) + +# import tensorflow as tf +# if tf.__version__.startswith('2'): +# tf.compat.v1.disable_eager_execution() + + + +# Let's use AAPL (Apple), MSI (Motorola), SBUX (Starbucks) +def get_data(): + # returns a T x 3 list of stock prices + # each row is a different stock + # 0 = AAPL + # 1 = MSI + # 2 = SBUX + df = pd.read_csv('aapl_msi_sbux.csv') + return df.values + + + +### The experience replay memory ### +class ReplayBuffer: + def __init__(self, obs_dim, act_dim, size): + self.obs1_buf = np.zeros([size, obs_dim], dtype=np.float32) + self.obs2_buf = np.zeros([size, obs_dim], dtype=np.float32) + self.acts_buf = np.zeros(size, dtype=np.uint8) + self.rews_buf = np.zeros(size, dtype=np.float32) + self.done_buf = np.zeros(size, dtype=np.uint8) + self.ptr, self.size, self.max_size = 0, 0, size + + def store(self, obs, act, rew, next_obs, done): + self.obs1_buf[self.ptr] = obs + self.obs2_buf[self.ptr] = next_obs + self.acts_buf[self.ptr] = act + self.rews_buf[self.ptr] = rew + self.done_buf[self.ptr] = done + self.ptr = (self.ptr+1) % self.max_size + self.size = min(self.size+1, self.max_size) + + def sample_batch(self, batch_size=32): + idxs = np.random.randint(0, self.size, size=batch_size) + return dict(s=self.obs1_buf[idxs], + s2=self.obs2_buf[idxs], + a=self.acts_buf[idxs], + r=self.rews_buf[idxs], + d=self.done_buf[idxs]) + + + + + +def get_scaler(env): + # return scikit-learn scaler object to scale the states + # Note: you could also populate the replay buffer here + + states = [] + for _ in range(env.n_step): + action = np.random.choice(env.action_space) + state, reward, done, info = env.step(action) + states.append(state) + if done: + break + + scaler = StandardScaler() + scaler.fit(states) + return scaler + + + + +def maybe_make_dir(directory): + if not os.path.exists(directory): + os.makedirs(directory) + + + + +def mlp(input_dim, n_action, n_hidden_layers=1, hidden_dim=32): + """ A multi-layer perceptron """ + + # input layer + i = Input(shape=(input_dim,)) + x = i + + # hidden layers + for _ in range(n_hidden_layers): + x = Dense(hidden_dim, activation='relu')(x) + + # final layer + x = Dense(n_action)(x) + + # make the model + model = Model(i, x) + + model.compile(loss='mse', optimizer='adam') + print((model.summary())) + return model + + + + +class MultiStockEnv: + """ + A 3-stock trading environment. + State: vector of size 7 (n_stock * 2 + 1) + - # shares of stock 1 owned + - # shares of stock 2 owned + - # shares of stock 3 owned + - price of stock 1 (using daily close price) + - price of stock 2 + - price of stock 3 + - cash owned (can be used to purchase more stocks) + Action: categorical variable with 27 (3^3) possibilities + - for each stock, you can: + - 0 = sell + - 1 = hold + - 2 = buy + """ + def __init__(self, data, initial_investment=20000): + # data + self.stock_price_history = data + self.n_step, self.n_stock = self.stock_price_history.shape + + # instance attributes + self.initial_investment = initial_investment + self.cur_step = None + self.stock_owned = None + self.stock_price = None + self.cash_in_hand = None + + self.action_space = np.arange(3**self.n_stock) + + # action permutations + # returns a nested list with elements like: + # [0,0,0] + # [0,0,1] + # [0,0,2] + # [0,1,0] + # [0,1,1] + # etc. + # 0 = sell + # 1 = hold + # 2 = buy + self.action_list = list(map(list, itertools.product([0, 1, 2], repeat=self.n_stock))) + + # calculate size of state + self.state_dim = self.n_stock * 2 + 1 + + self.reset() + + + def reset(self): + self.cur_step = 0 + self.stock_owned = np.zeros(self.n_stock) + self.stock_price = self.stock_price_history[self.cur_step] + self.cash_in_hand = self.initial_investment + return self._get_obs() + + + def step(self, action): + assert action in self.action_space + + # get current value before performing the action + prev_val = self._get_val() + + # perform the trade + self._trade(action) + + # update price, i.e. go to the next day + self.cur_step += 1 + self.stock_price = self.stock_price_history[self.cur_step] + + # get the new value after taking the action + cur_val = self._get_val() + + # reward is the increase in porfolio value + reward = cur_val - prev_val + + # done if we have run out of data + done = self.cur_step == self.n_step - 1 + + # store the current value of the portfolio here + info = {'cur_val': cur_val} + + # conform to the Gym API + return self._get_obs(), reward, done, info + + + def _get_obs(self): + obs = np.empty(self.state_dim) + obs[:self.n_stock] = self.stock_owned + obs[self.n_stock:2*self.n_stock] = self.stock_price + obs[-1] = self.cash_in_hand + return obs + + + + def _get_val(self): + return self.stock_owned.dot(self.stock_price) + self.cash_in_hand + + + def _trade(self, action): + # index the action we want to perform + # 0 = sell + # 1 = hold + # 2 = buy + # e.g. [2,1,0] means: + # buy first stock + # hold second stock + # sell third stock + action_vec = self.action_list[action] + + # determine which stocks to buy or sell + sell_index = [] # stores index of stocks we want to sell + buy_index = [] # stores index of stocks we want to buy + for i, a in enumerate(action_vec): + if a == 0: + sell_index.append(i) + elif a == 2: + buy_index.append(i) + + # sell any stocks we want to sell + # then buy any stocks we want to buy + if sell_index: + # NOTE: to simplify the problem, when we sell, we will sell ALL shares of that stock + for i in sell_index: + self.cash_in_hand += self.stock_price[i] * self.stock_owned[i] + self.stock_owned[i] = 0 + if buy_index: + # NOTE: when buying, we will loop through each stock we want to buy, + # and buy one share at a time until we run out of cash + can_buy = True + while can_buy: + for i in buy_index: + if self.cash_in_hand > self.stock_price[i]: + self.stock_owned[i] += 1 # buy one share + self.cash_in_hand -= self.stock_price[i] + else: + can_buy = False + + + + + +class DQNAgent(object): + def __init__(self, state_size, action_size): + self.state_size = state_size + self.action_size = action_size + self.memory = ReplayBuffer(state_size, action_size, size=500) + self.gamma = 0.95 # discount rate + self.epsilon = 1.0 # exploration rate + self.epsilon_min = 0.01 + self.epsilon_decay = 0.995 + self.model = mlp(state_size, action_size) + + + def update_replay_memory(self, state, action, reward, next_state, done): + self.memory.store(state, action, reward, next_state, done) + + + def act(self, state): + if np.random.rand() <= self.epsilon: + return np.random.choice(self.action_size) + act_values = self.model.predict(state, verbose=0) + return np.argmax(act_values[0]) # returns action + + + def replay(self, batch_size=32): + # first check if replay buffer contains enough data + if self.memory.size < batch_size: + return + + # sample a batch of data from the replay memory + minibatch = self.memory.sample_batch(batch_size) + states = minibatch['s'] + actions = minibatch['a'] + rewards = minibatch['r'] + next_states = minibatch['s2'] + done = minibatch['d'] + + # Calculate the tentative target: Q(s',a) + target = rewards + (1 - done) * self.gamma * np.amax(self.model.predict(next_states, verbose=0), axis=1) + + # With the Keras API, the target (usually) must have the same + # shape as the predictions. + # However, we only need to update the network for the actions + # which were actually taken. + # We can accomplish this by setting the target to be equal to + # the prediction for all values. + # Then, only change the targets for the actions taken. + # Q(s,a) + target_full = self.model.predict(states, verbose=0) + target_full[np.arange(batch_size), actions] = target + + # Run one training step + self.model.train_on_batch(states, target_full) + + if self.epsilon > self.epsilon_min: + self.epsilon *= self.epsilon_decay + + + def load(self, name): + self.model.load_weights(name) + + + def save(self, name): + self.model.save_weights(name) + + + +def play_one_episode(agent, env, is_train): + # note: after transforming states are already 1xD + state = env.reset() + state = scaler.transform([state]) + done = False + + while not done: + action = agent.act(state) + next_state, reward, done, info = env.step(action) + next_state = scaler.transform([next_state]) + if is_train == 'train': + agent.update_replay_memory(state, action, reward, next_state, done) + agent.replay(batch_size) + state = next_state + + return info['cur_val'] + + + +if __name__ == '__main__': + + # config + models_folder = 'rl_trader_models' + rewards_folder = 'rl_trader_rewards' + model_file = 'dqn.weights.h5' + num_episodes = 2000 + batch_size = 32 + initial_investment = 20000 + + + parser = argparse.ArgumentParser() + parser.add_argument('-m', '--mode', type=str, required=True, + help='either "train" or "test"') + args = parser.parse_args() + + maybe_make_dir(models_folder) + maybe_make_dir(rewards_folder) + + data = get_data() + n_timesteps, n_stocks = data.shape + + n_train = n_timesteps // 2 + + train_data = data[:n_train] + test_data = data[n_train:] + + env = MultiStockEnv(train_data, initial_investment) + state_size = env.state_dim + action_size = len(env.action_space) + agent = DQNAgent(state_size, action_size) + scaler = get_scaler(env) + + # store the final value of the portfolio (end of episode) + portfolio_value = [] + + if args.mode == 'test': + # then load the previous scaler + with open(f'{models_folder}/scaler.pkl', 'rb') as f: + scaler = pickle.load(f) + + # remake the env with test data + env = MultiStockEnv(test_data, initial_investment) + + # make sure epsilon is not 1! + # no need to run multiple episodes if epsilon = 0, it's deterministic + agent.epsilon = 0.01 + + # load trained weights + agent.load(f'{models_folder}/{model_file}') + + # play the game num_episodes times + for e in range(num_episodes): + t0 = datetime.now() + val = play_one_episode(agent, env, args.mode) + dt = datetime.now() - t0 + print(f"episode: {e + 1}/{num_episodes}, episode end value: {val:.2f}, duration: {dt}") + portfolio_value.append(val) # append episode end portfolio value + + # save the weights when we are done + if args.mode == 'train': + # save the DQN + agent.save(f'{models_folder}/{model_file}') + + # save the scaler + with open(f'{models_folder}/scaler.pkl', 'wb') as f: + pickle.dump(scaler, f) + + + # save portfolio value for each episode + np.save(f'{rewards_folder}/{args.mode}.npy', portfolio_value) diff --git a/tf2.0/mlp_trader.py b/tf2.0/mlp_trader.py new file mode 100644 index 00000000..e5d53e56 --- /dev/null +++ b/tf2.0/mlp_trader.py @@ -0,0 +1,401 @@ +import numpy as np +import pandas as pd + +from sklearn.neural_network import MLPRegressor +from sklearn.preprocessing import StandardScaler + +from datetime import datetime +import itertools +import argparse +import re +import os +import pickle + + +# Let's use AAPL (Apple), MSI (Motorola), SBUX (Starbucks) +def get_data(): + # returns a T x 3 list of stock prices + # each row is a different stock + # 0 = AAPL + # 1 = MSI + # 2 = SBUX + df = pd.read_csv('aapl_msi_sbux.csv') + return df.values + + + +### The experience replay memory ### +class ReplayBuffer: + def __init__(self, obs_dim, act_dim, size): + self.obs1_buf = np.zeros([size, obs_dim], dtype=np.float32) + self.obs2_buf = np.zeros([size, obs_dim], dtype=np.float32) + self.acts_buf = np.zeros(size, dtype=np.uint8) + self.rews_buf = np.zeros(size, dtype=np.float32) + self.done_buf = np.zeros(size, dtype=np.uint8) + self.ptr, self.size, self.max_size = 0, 0, size + + def store(self, obs, act, rew, next_obs, done): + self.obs1_buf[self.ptr] = obs + self.obs2_buf[self.ptr] = next_obs + self.acts_buf[self.ptr] = act + self.rews_buf[self.ptr] = rew + self.done_buf[self.ptr] = done + self.ptr = (self.ptr+1) % self.max_size + self.size = min(self.size+1, self.max_size) + + def sample_batch(self, batch_size=32): + idxs = np.random.randint(0, self.size, size=batch_size) + return dict(s=self.obs1_buf[idxs], + s2=self.obs2_buf[idxs], + a=self.acts_buf[idxs], + r=self.rews_buf[idxs], + d=self.done_buf[idxs]) + + + + + +def get_scaler(env): + # return scikit-learn scaler object to scale the states + # Note: you could also populate the replay buffer here + + states = [] + for _ in range(env.n_step): + action = np.random.choice(env.action_space) + state, reward, done, info = env.step(action) + states.append(state) + if done: + break + + scaler = StandardScaler() + scaler.fit(states) + return scaler + + + + +def maybe_make_dir(directory): + if not os.path.exists(directory): + os.makedirs(directory) + + + + +def mlp(input_dim, n_action, n_hidden_layers=1, hidden_dim=32): + """ A multi-layer perceptron """ + + model = MLPRegressor( + hidden_layer_sizes=n_hidden_layers * [hidden_dim], + ) + + # since we'll be first using this to make a prediction with random weights + # we need to know the output size + + # so we'll just start by fitting on some dummy data + X = np.random.randn(100, input_dim) + Y = np.random.randn(100, n_action) + model.partial_fit(X, Y) + + return model + + + + +class MultiStockEnv: + """ + A 3-stock trading environment. + State: vector of size 7 (n_stock * 2 + 1) + - # shares of stock 1 owned + - # shares of stock 2 owned + - # shares of stock 3 owned + - price of stock 1 (using daily close price) + - price of stock 2 + - price of stock 3 + - cash owned (can be used to purchase more stocks) + Action: categorical variable with 27 (3^3) possibilities + - for each stock, you can: + - 0 = sell + - 1 = hold + - 2 = buy + """ + def __init__(self, data, initial_investment=20000): + # data + self.stock_price_history = data + self.n_step, self.n_stock = self.stock_price_history.shape + + # instance attributes + self.initial_investment = initial_investment + self.cur_step = None + self.stock_owned = None + self.stock_price = None + self.cash_in_hand = None + + self.action_space = np.arange(3**self.n_stock) + + # action permutations + # returns a nested list with elements like: + # [0,0,0] + # [0,0,1] + # [0,0,2] + # [0,1,0] + # [0,1,1] + # etc. + # 0 = sell + # 1 = hold + # 2 = buy + self.action_list = list(map(list, itertools.product([0, 1, 2], repeat=self.n_stock))) + + # calculate size of state + self.state_dim = self.n_stock * 2 + 1 + + self.reset() + + + def reset(self): + self.cur_step = 0 + self.stock_owned = np.zeros(self.n_stock) + self.stock_price = self.stock_price_history[self.cur_step] + self.cash_in_hand = self.initial_investment + return self._get_obs() + + + def step(self, action): + assert action in self.action_space + + # get current value before performing the action + prev_val = self._get_val() + + # perform the trade + self._trade(action) + + # update price, i.e. go to the next day + self.cur_step += 1 + self.stock_price = self.stock_price_history[self.cur_step] + + # get the new value after taking the action + cur_val = self._get_val() + + # reward is the increase in porfolio value + reward = cur_val - prev_val + + # done if we have run out of data + done = self.cur_step == self.n_step - 1 + + # store the current value of the portfolio here + info = {'cur_val': cur_val} + + # conform to the Gym API + return self._get_obs(), reward, done, info + + + def _get_obs(self): + obs = np.empty(self.state_dim) + obs[:self.n_stock] = self.stock_owned + obs[self.n_stock:2*self.n_stock] = self.stock_price + obs[-1] = self.cash_in_hand + return obs + + + + def _get_val(self): + return self.stock_owned.dot(self.stock_price) + self.cash_in_hand + + + def _trade(self, action): + # index the action we want to perform + # 0 = sell + # 1 = hold + # 2 = buy + # e.g. [2,1,0] means: + # buy first stock + # hold second stock + # sell third stock + action_vec = self.action_list[action] + + # determine which stocks to buy or sell + sell_index = [] # stores index of stocks we want to sell + buy_index = [] # stores index of stocks we want to buy + for i, a in enumerate(action_vec): + if a == 0: + sell_index.append(i) + elif a == 2: + buy_index.append(i) + + # sell any stocks we want to sell + # then buy any stocks we want to buy + if sell_index: + # NOTE: to simplify the problem, when we sell, we will sell ALL shares of that stock + for i in sell_index: + self.cash_in_hand += self.stock_price[i] * self.stock_owned[i] + self.stock_owned[i] = 0 + if buy_index: + # NOTE: when buying, we will loop through each stock we want to buy, + # and buy one share at a time until we run out of cash + can_buy = True + while can_buy: + for i in buy_index: + if self.cash_in_hand > self.stock_price[i]: + self.stock_owned[i] += 1 # buy one share + self.cash_in_hand -= self.stock_price[i] + else: + can_buy = False + + + + + +class DQNAgent(object): + def __init__(self, state_size, action_size): + self.state_size = state_size + self.action_size = action_size + self.memory = ReplayBuffer(state_size, action_size, size=500) + self.gamma = 0.95 # discount rate + self.epsilon = 1.0 # exploration rate + self.epsilon_min = 0.01 + self.epsilon_decay = 0.995 + self.model = mlp(state_size, action_size) + + + def update_replay_memory(self, state, action, reward, next_state, done): + self.memory.store(state, action, reward, next_state, done) + + + def act(self, state): + if np.random.rand() <= self.epsilon: + return np.random.choice(self.action_size) + act_values = self.model.predict(state) + return np.argmax(act_values[0]) # returns action + + def replay(self, batch_size=32): + # first check if replay buffer contains enough data + if self.memory.size < batch_size: + return + + # sample a batch of data from the replay memory + minibatch = self.memory.sample_batch(batch_size) + states = minibatch['s'] + actions = minibatch['a'] + rewards = minibatch['r'] + next_states = minibatch['s2'] + done = minibatch['d'] + + # Calculate the tentative target: Q(s',a) + target = rewards + (1 - done) * self.gamma * np.amax(self.model.predict(next_states), axis=1) + + # With the Keras API, the target (usually) must have the same + # shape as the predictions. + # However, we only need to update the network for the actions + # which were actually taken. + # We can accomplish this by setting the target to be equal to + # the prediction for all values. + # Then, only change the targets for the actions taken. + # Q(s,a) + target_full = self.model.predict(states) + target_full[np.arange(batch_size), actions] = target + + # Run one training step + self.model.partial_fit(states, target_full) + + if self.epsilon > self.epsilon_min: + self.epsilon *= self.epsilon_decay + + + def load(self, name): + with open(name, "rb") as f: + self.model = pickle.load(f) + + + def save(self, name): + with open(name, "wb") as f: + pickle.dump(self.model, f) + + +def play_one_episode(agent, env, is_train): + # note: after transforming states are already 1xD + state = env.reset() + state = scaler.transform([state]) + done = False + + while not done: + action = agent.act(state) + next_state, reward, done, info = env.step(action) + next_state = scaler.transform([next_state]) + if is_train == 'train': + agent.update_replay_memory(state, action, reward, next_state, done) + agent.replay(batch_size) + state = next_state + + return info['cur_val'] + + + +if __name__ == '__main__': + + # config + models_folder = 'rl_trader_models' + rewards_folder = 'rl_trader_rewards' + num_episodes = 2000 + batch_size = 32 + initial_investment = 20000 + + + parser = argparse.ArgumentParser() + parser.add_argument('-m', '--mode', type=str, required=True, + help='either "train" or "test"') + args = parser.parse_args() + + maybe_make_dir(models_folder) + maybe_make_dir(rewards_folder) + + data = get_data() + n_timesteps, n_stocks = data.shape + + n_train = n_timesteps // 2 + + train_data = data[:n_train] + test_data = data[n_train:] + + env = MultiStockEnv(train_data, initial_investment) + state_size = env.state_dim + action_size = len(env.action_space) + agent = DQNAgent(state_size, action_size) + scaler = get_scaler(env) + + # store the final value of the portfolio (end of episode) + portfolio_value = [] + + if args.mode == 'test': + # then load the previous scaler + with open(f'{models_folder}/scaler.pkl', 'rb') as f: + scaler = pickle.load(f) + + # remake the env with test data + env = MultiStockEnv(test_data, initial_investment) + + # make sure epsilon is not 1! + # no need to run multiple episodes if epsilon = 0, it's deterministic + agent.epsilon = 0.01 + + # load trained weights + agent.load(f'{models_folder}/mlp.pkl') + + # play the game num_episodes times + for e in range(num_episodes): + t0 = datetime.now() + val = play_one_episode(agent, env, args.mode) + dt = datetime.now() - t0 + print(f"episode: {e + 1}/{num_episodes}, episode end value: {val:.2f}, duration: {dt}") + portfolio_value.append(val) # append episode end portfolio value + + # save the weights when we are done + if args.mode == 'train': + # save the DQN + agent.save(f'{models_folder}/mlp.pkl') + + # save the scaler + with open(f'{models_folder}/scaler.pkl', 'wb') as f: + pickle.dump(scaler, f) + + + # save portfolio value for each episode + np.save(f'{rewards_folder}/{args.mode}.npy', portfolio_value) diff --git a/tf2.0/rl_trader.py b/tf2.0/rl_trader.py index 2f98b964..b5849494 100644 --- a/tf2.0/rl_trader.py +++ b/tf2.0/rl_trader.py @@ -15,6 +15,11 @@ from sklearn.preprocessing import StandardScaler +import tensorflow as tf +# if tf.__version__.startswith('2'): +# tf.compat.v1.disable_eager_execution() + + # Let's use AAPL (Apple), MSI (Motorola), SBUX (Starbucks) def get_data(): # returns a T x 3 list of stock prices @@ -172,13 +177,13 @@ def step(self, action): # get current value before performing the action prev_val = self._get_val() + # perform the trade + self._trade(action) + # update price, i.e. go to the next day self.cur_step += 1 self.stock_price = self.stock_price_history[self.cur_step] - # perform the trade - self._trade(action) - # get the new value after taking the action cur_val = self._get_val() @@ -270,10 +275,10 @@ def update_replay_memory(self, state, action, reward, next_state, done): def act(self, state): if np.random.rand() <= self.epsilon: return np.random.choice(self.action_size) - act_values = self.model.predict(state) + act_values = self.model.predict(state, verbose=0) return np.argmax(act_values[0]) # returns action - + @tf.function def replay(self, batch_size=32): # first check if replay buffer contains enough data if self.memory.size < batch_size: @@ -288,7 +293,7 @@ def replay(self, batch_size=32): done = minibatch['d'] # Calculate the tentative target: Q(s',a) - target = rewards + (1 - done) * self.gamma * np.amax(self.model.predict(next_states), axis=1) + target = rewards + (1 - done) * self.gamma * np.amax(self.model.predict(next_states, verbose=0), axis=1) # With the Keras API, the target (usually) must have the same # shape as the predictions. @@ -298,7 +303,7 @@ def replay(self, batch_size=32): # the prediction for all values. # Then, only change the targets for the actions taken. # Q(s,a) - target_full = self.model.predict(states) + target_full = self.model.predict(states, verbose=0) target_full[np.arange(batch_size), actions] = target # Run one training step @@ -316,6 +321,7 @@ def save(self, name): self.model.save_weights(name) + def play_one_episode(agent, env, is_train): # note: after transforming states are already 1xD state = env.reset() @@ -340,6 +346,7 @@ def play_one_episode(agent, env, is_train): # config models_folder = 'rl_trader_models' rewards_folder = 'rl_trader_rewards' + model_file = 'dqn.weights.h5' num_episodes = 2000 batch_size = 32 initial_investment = 20000 @@ -383,7 +390,7 @@ def play_one_episode(agent, env, is_train): agent.epsilon = 0.01 # load trained weights - agent.load(f'{models_folder}/dqn.h5') + agent.load(f'{models_folder}/{model_file}') # play the game num_episodes times for e in range(num_episodes): @@ -396,7 +403,7 @@ def play_one_episode(agent, env, is_train): # save the weights when we are done if args.mode == 'train': # save the DQN - agent.save(f'{models_folder}/dqn.h5') + agent.save(f'{models_folder}/{model_file}') # save the scaler with open(f'{models_folder}/scaler.pkl', 'wb') as f: @@ -404,4 +411,4 @@ def play_one_episode(agent, env, is_train): # save portfolio value for each episode - np.save(f'{rewards_folder}/{args.mode}.npy', portfolio_value) + np.save(f'{rewards_folder}/{args.mode}.npy', portfolio_value) \ No newline at end of file diff --git a/timeseries/WHERE ARE THE NOTEBOOKS.txt b/timeseries/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/timeseries/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/transformers/WHERE ARE THE NOTEBOOKS.txt b/transformers/WHERE ARE THE NOTEBOOKS.txt new file mode 100644 index 00000000..5446ce25 --- /dev/null +++ b/transformers/WHERE ARE THE NOTEBOOKS.txt @@ -0,0 +1,5 @@ +As stated in the "where to get the code" / "where to get the notebooks" lecture, the notebooks are NOT on Github. + +If you missed this, please review the lecture for the actual location of the notebooks. + +If, after reviewing it, you still need assistance, please contact info@deeplearningcourses.com. \ No newline at end of file diff --git a/transformers/extra_reading.txt b/transformers/extra_reading.txt new file mode 100644 index 00000000..718e2963 --- /dev/null +++ b/transformers/extra_reading.txt @@ -0,0 +1,32 @@ +Attention Is All You Need +https://arxiv.org/abs/1706.03762 + +BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding +https://arxiv.org/abs/1810.04805v2 + +Improving Language Understanding by Generative Pre-Training (GPT) +https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf + +Improving Language Understanding with Unsupervised Learning +https://openai.com/blog/language-unsupervised/ + +Language Models are Unsupervised Multitask Learners (GPT-2) +https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf + +Better Language Models and Their Implications +https://openai.com/blog/better-language-models/ + +Language Models are Few-Shot Learners (GPT-3) +https://arxiv.org/abs/2005.14165 + +List of Hugging Face Pipelines for NLP +https://lazyprogrammer.me/list-of-hugging-face-pipelines-for-nlp/ + +BitFit: Simple Parameter-efficient Fine-tuning for Transformer-based Masked Language-models +https://arxiv.org/abs/2106.10199 + +Translation Datasets +https://opus.nlpl.eu/KDE4.php + +Layer Normalization +https://arxiv.org/abs/1607.06450 \ No newline at end of file diff --git a/unsupervised_class/kmeans_mnist.py b/unsupervised_class/kmeans_mnist.py index fd7ca76e..b399afab 100644 --- a/unsupervised_class/kmeans_mnist.py +++ b/unsupervised_class/kmeans_mnist.py @@ -16,7 +16,7 @@ import numpy as np import pandas as pd import matplotlib.pyplot as plt -from kmeans import plot_k_means, get_simple_data +from .kmeans import plot_k_means, get_simple_data from datetime import datetime def get_data(limit=None): diff --git a/unsupervised_class/tweets.py b/unsupervised_class/tweets.py index aeb4552a..6ffba008 100644 --- a/unsupervised_class/tweets.py +++ b/unsupervised_class/tweets.py @@ -66,7 +66,7 @@ def filter_tweet(s): # transform the text into a data matrix tfidf = TfidfVectorizer(max_features=100, stop_words=stopwords) -X = tfidf.fit_transform(text).todense() +X = tfidf.fit_transform(text).asformat('array') # subsample for efficiency diff --git a/unsupervised_class3/bayes_classifier_gmm.py b/unsupervised_class3/bayes_classifier_gmm.py index b129c522..f3c7dd0f 100644 --- a/unsupervised_class3/bayes_classifier_gmm.py +++ b/unsupervised_class3/bayes_classifier_gmm.py @@ -28,7 +28,7 @@ def fit(self, X, Y): print("Fitting gmm", k) Xk = X[Y == k] self.p_y[k] = len(Xk) - gmm = BayesianGaussianMixture(10) + gmm = BayesianGaussianMixture(n_components=10) gmm.fit(Xk) self.gaussians.append(gmm) # normalize p(y)