Deep Learning

- added examples
- added requirements
- fixed bug with ML MLP
This commit is contained in:
2024-08-23 17:03:39 +02:00
parent 9ea43beace
commit 7ff3032d3c
9 changed files with 1110 additions and 7 deletions

View File

@@ -1,4 +1,8 @@
matplotlib
pandas
keras
jax[cuda12]
pydot
matplotlib
pandas
tqdm
scikit-learn
scikit-learn

View File

@@ -114,13 +114,13 @@ if __name__ == "__main__":
#rand = 347617386 # LoR for electrical_grid
#rand = 834535453 # LoR for heart
#rand = 1793295160 # MLP for iris
#rand = 629702080 # MLP for frogs
#rand = 772284034 # MLP for frogs
#rand = 1038336550 # KMe for frogs_no_target
np.random.seed(rand)
print(f"Using seed: {rand}")
ds, ml, sk = power_plant()
ds, ml, sk = frogs()
epochs, _, _ = ml.learn(1000, verbose=True)
ml.display_results()

37
src/deep/dl.py Normal file
View File

@@ -0,0 +1,37 @@
# ***********************************************************
# Esercizio 1.A
# L'esercizio prevede la costruzione di un generatore di caption di immagini.
# Utilizzando il tool preferito, costruire una CNN in grado di costruire
# un suitable embedding di un immagine, il quale verrà passato ad una RNN
# per la generazione del testo della caption.
# Per il training utilizzare il Flickr Dataset.
# https://www.kaggle.com/datasets/hsankesara/flickr-image-dataset
# # Esercizio 1.B
# L'esercizio consiste nell'applicare una delle tecniche viste a lezione
# per l'object detection tramite bounding box per costruire un riconoscitore
# di oggetti all'interno di una immagine presa con una fotocamera.
# Il dataset da utilizzare è Object365, un dataset di HQ (high-quality)
# immagini con bounding boxes di oggetti.
# Contiene 365 oggetti, 600k immagini, e 10 milioni di bounding boxes.
# Se necessario eseguire un subsampling per ridurre le dimensioni del dataset.
# from ultralytics import YOLO
# model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training)
# model.train(data='Objects365.yaml', epochs=100, imgsz=640)
# ***********************************************************
# Esercizio 2.A
# Realizzare un sistema di pulizia immagini (image denoising),
# basato su una opportuna architettura ad Autoencoder,
# che prendendo in input un dataset di immagini soggette a "rumore"
# ne restituisca una versione "pulita".
# Utilizzare il dataset Fashion-MNIST (inserire un opportuno filtro di noise per ottenere l'input)
# https://www.kaggle.com/datasets/zalando-research/fashionmnist
# Esercizio 2.B
# Realizzare un sistema di text classification per frasi (sequenze testuali)
# che possono essere considerate "positive" o "negative"(sentiment analysis).
# Il sistema deve basarsi sull'uso di architetture transformer.
# Suggerimento: vedere modelli offerti da HuggingFace.
# Alcuni dataset suggeriti su kaggle: https://www.kaggle.com/datasets?search=sentiment+analysis

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,191 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_1\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_1\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ embedding (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">160,000</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ lstm (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">LSTM</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">100</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">53,200</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">101</span> │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"</pre>\n"
],
"text/plain": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ embedding (\u001b[38;5;33mEmbedding\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m500\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m160,000\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ lstm (\u001b[38;5;33mLSTM\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m100\u001b[0m) │ \u001b[38;5;34m53,200\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m101\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">213,301</span> (833.21 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m213,301\u001b[0m (833.21 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">213,301</span> (833.21 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m213,301\u001b[0m (833.21 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"None\n",
"Epoch 1/3\n",
"\u001b[1m391/391\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m33s\u001b[0m 80ms/step - accuracy: 0.6408 - loss: 0.5984 - val_accuracy: 0.8401 - val_loss: 0.3739\n",
"Epoch 2/3\n",
"\u001b[1m391/391\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m40s\u001b[0m 100ms/step - accuracy: 0.8704 - loss: 0.3201 - val_accuracy: 0.8371 - val_loss: 0.3736\n",
"Epoch 3/3\n",
"\u001b[1m391/391\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m39s\u001b[0m 100ms/step - accuracy: 0.8787 - loss: 0.2981 - val_accuracy: 0.8701 - val_loss: 0.3126\n",
"\u001b[1m782/782\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m35s\u001b[0m 44ms/step - accuracy: 0.8677 - loss: 0.3171\n",
"Accuracy: 87.01%\n"
]
}
],
"source": [
"# -*- coding: utf-8 -*-\n",
"\"\"\"\n",
"Created on Wed Feb 23 10:29:02 2022\n",
"\n",
"@author: Luigi Portinale\n",
"\"\"\"\n",
"#The Large Movie Review Dataset (often referred to as the IMDB dataset) \n",
"#contains 25,000 highly-polar movie reviews (good or bad) for training \n",
"#and the same amount again for testing. \n",
"#The problem is to determine whether a given movie review has \n",
"#a positive or negative sentiment.\n",
"\n",
"#Word Embedding\n",
"#We will map each word onto a 32 length real valued vector. \n",
"#We will also limit the total number of words that we are interested \n",
"#in modeling to the 5000 most frequent words, and zero out the rest. \n",
"#Finally, the sequence length (number of words) in each review varies, \n",
"#so we will constrain each review to be 500 words, \n",
"#truncating long reviews and pad the shorter reviews with zero values.\n",
"\n",
"import numpy\n",
"from keras.api.datasets import imdb\n",
"from keras.api.models import Sequential\n",
"from keras.api.layers import Dense\n",
"from keras.api.layers import LSTM\n",
"from keras.api.layers import Embedding\n",
"from keras.api.layers import Input\n",
"from keras.api.preprocessing import sequence\n",
"\n",
"# fix random seed for reproducibility\n",
"numpy.random.seed(7)\n",
"# load the dataset but only keep the top n words, zero the rest\n",
"top_words = 5000\n",
"(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)\n",
"# truncate and pad input sequences\n",
"max_review_length = 500\n",
"X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)\n",
"X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)\n",
"\n",
"\n",
"# create the model\n",
"embedding_vector_length = 32\n",
"model = Sequential()\n",
"#create the emebedding of the documents\n",
"model.add(Input(shape=(max_review_length,)))\n",
"model.add(Embedding(top_words, embedding_vector_length))\n",
"\n",
"#add an LSTM with 100 units and drop-out on both the input\n",
"#and the recurrent connections\n",
"model.add(LSTM(100, recurrent_dropout=0.05, dropout=0.01))\n",
"\n",
"#output layer for binary classification\n",
"model.add(Dense(1, activation='sigmoid'))\n",
"\n",
"model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
"print(model.summary())\n",
"model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3, batch_size=64)\n",
"\n",
"# Final evaluation of the model\n",
"scores = model.evaluate(X_test, y_test, verbose=1)\n",
"print(\"Accuracy: %.2f%%\" % (scores[1]*100))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,100 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# -*- coding: utf-8 -*-\n",
"\"\"\"\n",
"Created on Wed Feb 23 10:53:10 2022\n",
"\n",
"@author: Luigi Portinale\n",
"\"\"\"\n",
"from numpy import array\n",
"from keras.api.preprocessing.sequence import pad_sequences\n",
"from keras.api.models import Sequential\n",
"from keras.api.layers import Dense\n",
"from keras.api.layers import Flatten\n",
"from keras.api.layers import Embedding\n",
"from keras.api.layers import Input\n",
"#from keras.utils.vis_utils import plot_model\n",
"\n",
"# define documents\n",
"docs = ['Well done!',\n",
"\t\t'Good work',\n",
"\t\t'Great effort',\n",
"\t\t'nice work',\n",
"\t\t'Excellent!',\n",
"\t\t'Weak',\n",
"\t\t'Poor effort!',\n",
"\t\t'not good',\n",
"\t\t'poor work',\n",
"\t\t'Could have done better.']\n",
"# define class labels (1: positive; 0: negative)\n",
"labels = array([1,1,1,1,1,0,0,0,0,0])\n",
"\n",
"def custom_one_hot(doc, vocab_size):\n",
" words = doc.split()\n",
" encoded = [hash(word) % vocab_size for word in words]\n",
" return encoded\n",
"\n",
"# integer encode the documents\n",
"#keras tensorflow one_hot(d,s) is a hash function returning an integer \n",
"#for each word d; it uses a vocabulary size s that should be the number\n",
"#of possible words to hash. If this is greater than the actual vocabulary\n",
"#size then the probability of collisions is reduced\n",
"vocab_size = 50\n",
"encoded_docs = [custom_one_hot(d, vocab_size) for d in docs]\n",
"print(\"The encoded documents:\")\n",
"print(encoded_docs)\n",
"# pad documents to a max length of 4 words\n",
"max_length = 4\n",
"padded_docs = pad_sequences(encoded_docs, maxlen=max_length, padding='post')\n",
"# each document is then a vector of 4 integers!\n",
"print(\"The padded documents:\")\n",
"print(padded_docs)\n",
"\n",
"\n",
"# define the model\n",
"model = Sequential()\n",
"\n",
"#The Embedding has a vocabulary of 50 and an input length of 4. \n",
"#We will choose a small embedding space of 8 dimensions.\n",
"#Embedding needs: the vocabulary size, \n",
"#the embedding output dimension (each word will be embedded in a vector\n",
"#with this dimension) that is the output size of the layer and \n",
"#finally the length of each document that\n",
"#will be provided in input (input size of the layer)\n",
"model.add(Input(shape=(max_length,)))\n",
"model.add(Embedding(vocab_size, 8))\n",
"# each document in input at the above layer will have a vector\n",
"#of 8 integers for every word in the document\n",
"\n",
"#now we flatten the output of the embeddings\n",
"model.add(Flatten())\n",
"#then we use an outout layer for binary classification\n",
"model.add(Dense(1, activation='sigmoid'))\n",
"\n",
"#plot_model(model, to_file='model_plot.png', show_shapes=True, show_layer_names=True)\n",
"# compile the model\n",
"model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n",
"# summarize the model\n",
"print(model.summary())\n",
"# fit the model\n",
"model.fit(padded_docs, labels, epochs=100, verbose=1)\n",
"# evaluate the model\n",
"loss, accuracy = model.evaluate(padded_docs, labels, verbose=1)\n",
"print('Accuracy: %f' % (accuracy*100))"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -85,8 +85,9 @@ class MultiLayerPerceptron(MLAlgorithm):
def _h0(self, x:np.ndarray) -> np.ndarray:
self.activations = [x]
for layer in self.layers:
x = lrelu(with_bias(x).dot(layer))
for i, layer in enumerate(self.layers):
x = with_bias(x).dot(layer)
if i + 1 < len(self.layers): x = lrelu(x)
self.activations.append(x) # saving activation result
return softmax(x)