pickel-cancer-rick/project-cancer-classificati...

797 lines
76 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "8bc02404-8cd1-46d9-8237-2d035ebb3e79",
"metadata": {},
"source": [
"# **[Project] Cancer Subtype Classification**"
]
},
{
"cell_type": "markdown",
"id": "0c5076f4",
"metadata": {},
"source": [
"# Introduction"
]
},
{
"cell_type": "markdown",
"id": "8a599748",
"metadata": {},
"source": [
"The [TCGA Kidney Cancers Dataset](https://archive.ics.uci.edu/dataset/892/tcga+kidney+cancers) is a bulk RNA-seq dataset that contains transcriptome profiles (i.e., gene expression quantification data) of patients diagnosed with three different subtypes of kidney cancers.\n",
"This dataset can be used to make predictions about the specific subtype of kidney cancers given the normalized transcriptome profile data.\n",
"\n",
"The normalized transcriptome profile data is given as **TPM** and **FPKM** for each gene.\n",
"\n",
"> TPM (Transcripts Per Million) and FPKM (Fragments Per Kilobase Million) are two common methods for quantifying gene expression in RNA sequencing data.\n",
"> They both aim to account for the differences in sequencing depth and transcript length when estimating gene expression levels.\n",
">\n",
"> **TPM** (Transcripts Per Million):\n",
"> - TPM is a measure of gene expression that normalizes for both library size (sequencing depth) and transcript length.\n",
"> - The main idea behind TPM is to express the abundance of a transcript relative to the total number of transcripts in a sample, scaled to one million.\n",
">\n",
"> **FPKM** (Fragments Per Kilobase Million):\n",
"> - FPKM is another method for quantifying gene expression, which is commonly used in older RNA-seq analysis pipelines. It's similar in concept to TPM but differs in the way it's calculated.\n",
"> - FPKM also normalizes for library size and transcript length, but it measures gene expression as the number of fragments (i.e., reads) per kilobase of exon model per million reads.\n",
">\n",
"> TPM is generally considered more robust to variations in library size, making it a preferred choice in many modern RNA-seq analysis workflows.\n",
"\n",
"We provide one dataset for each kidney cancer subtype:\n",
"\n",
"- [TCGA-KICH](https://portal.gdc.cancer.gov/projects/TCGA-KICH): kidney chromophobe (renal clear cell carcinoma)\n",
"- [TCGA-KIRC](https://portal.gdc.cancer.gov/projects/TCGA-KIRC): kidney renal clear cell carcinoma\n",
"- [TCGA-KIRP](https://portal.gdc.cancer.gov/projects/TCGA-KIRP): kidney renal papillary cell carcinoma\n",
"\n",
"> This and _much_ more data is openly available on the [NCI Genomic Data Commons (GDC) Data Portal](https://portal.gdc.cancer.gov/)."
]
},
{
"cell_type": "markdown",
"id": "16712787",
"metadata": {},
"source": [
"# Data access"
]
},
{
"cell_type": "markdown",
"id": "6421ef6c",
"metadata": {},
"source": [
"There are two ways to access the data: via the TNT homepage or the GDC Data Portal."
]
},
{
"cell_type": "markdown",
"id": "b977e8b8",
"metadata": {},
"source": [
"## Download from the TNT homepage (_recommended_)"
]
},
{
"cell_type": "markdown",
"id": "800fa7bd",
"metadata": {},
"source": [
"The download from the TNT homepage is straightforward:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "dda97b16",
"metadata": {
"tags": []
},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (2666948873.py, line 6)",
"output_type": "error",
"traceback": [
"\u001b[0;36m Cell \u001b[0;32mIn[1], line 6\u001b[0;36m\u001b[0m\n\u001b[0;31m from IPython.display import clear_output(wait=True)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"! wget http://www.tnt.uni-hannover.de/edu/vorlesungen/AMLG/data/project-cancer-classification.tar.gz\n",
"! tar -xzvf project-cancer-classification.tar.gz\n",
"! mv -v project-cancer-classification/ data/\n",
"! rm -v project-cancer-classification.tar.gz"
]
},
{
"cell_type": "markdown",
"id": "bc2db880",
"metadata": {},
"source": [
"In the `data/` folder you will now find many files in the [TSV format](https://en.wikipedia.org/wiki/Tab-separated_values) ([CSV](https://en.wikipedia.org/wiki/Comma-separated_values)-like with tabs as delimiter) containing the normalized transcriptome profile data.\n",
"\n",
"To start, you can read a TSV file into a [pandas](https://pandas.pydata.org) [`DataFrame`](pandas dataframe to dict) using the [`pandas.read_csv()`](https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html#pandas-read-csv) function with the `sep` parameter set to `\\t`:"
]
},
{
"cell_type": "markdown",
"id": "ed50d396-fe33-47a7-ad19-8eb975ef0fa5",
"metadata": {},
"source": [
"## Lesen der DNA-Sequenz Dateien und speichern in einer Datei"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "2adae4ff",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Es wurden 1034 Dateien eingelesen.\n"
]
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import pickle\n",
"\n",
"\n",
"import os\n",
"#'./data/tcga-kirp-geq'\n",
"\n",
"labels = [\"kirp\", \"kirc\", \"kich\"] # Setzen Sie hier Ihren Ordnerpfad ein\n",
"n_files = 0\n",
"y = list()\n",
"x = list()\n",
"\n",
"rick = list()\n",
"data = []\n",
"\n",
"for l in labels:\n",
" root_folder = f\"./data/tcga-{l}-geq\"\n",
" for root, dirs, files in os.walk(root_folder):\n",
" for file in files:\n",
" if file.endswith('.tsv'):\n",
" n_files += 1\n",
" # Vollständiger Pfad zur Datei\n",
" file_path = os.path.join(root, file)\n",
" # Hier können Sie etwas mit der Datei machen, z.B. einlesen\n",
" df = pd.read_csv(filepath_or_buffer=file_path, sep=\"\\t\", header=1)\n",
" df = df['tpm_unstranded']\n",
"\n",
" df = df[4:]\n",
" df = np.array(df)\n",
" rick.append(df)\n",
" \n",
" data.append([df, l])\n",
"\n",
"print(f\"Es wurden {n_files} Dateien eingelesen.\")\n",
"#tsv_file_path = \"data/tcga-kich-geq/0ba21ef5-0829-422e-a674-d3817498c333/4868e8fc-e045-475a-a81d-ef43eabb7066.rna_seq.augmented_star_gene_counts.tsv\"\n",
"\n",
"# Read the TSV file into a DataFrame\n",
"#df = pd.read_csv(filepath_or_buffer=tsv_file_path, sep=\"\\t\", header=1)\n",
"\n",
"# Display the first few rows of the DataFrame\n",
"#print(df.head(n=20))\n",
"rick = np.array(rick)\n",
"\n",
"# Speichern der 'kirp' Liste in einer Pickle-Datei\n",
"with open('rick.pickle', 'wb') as f:\n",
" pickle.dump(rick, f)\n"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "dfe4f964-6068-46da-8103-194525086f01",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>genome_frequencies</th>\n",
" <th>cancer_type</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>[20.331, 0.0, 25.1806, 1.1301, 0.4836, 7.3269,...</td>\n",
" <td>kirp</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>[37.0405, 0.5002, 77.4246, 4.2188, 1.0408, 29....</td>\n",
" <td>kirp</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>[45.4456, 0.0903, 74.9545, 4.843, 1.5188, 11.8...</td>\n",
" <td>kirp</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>[15.2345, 0.3393, 62.0003, 2.4412, 0.932, 2.66...</td>\n",
" <td>kirp</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>[35.0709, 0.2333, 62.8022, 2.8872, 1.0547, 18....</td>\n",
" <td>kirp</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" genome_frequencies cancer_type\n",
"0 [20.331, 0.0, 25.1806, 1.1301, 0.4836, 7.3269,... kirp\n",
"1 [37.0405, 0.5002, 77.4246, 4.2188, 1.0408, 29.... kirp\n",
"2 [45.4456, 0.0903, 74.9545, 4.843, 1.5188, 11.8... kirp\n",
"3 [15.2345, 0.3393, 62.0003, 2.4412, 0.932, 2.66... kirp\n",
"4 [35.0709, 0.2333, 62.8022, 2.8872, 1.0547, 18.... kirp"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data_Frame = pd.DataFrame(data, columns=[\"genome_frequencies\", \"cancer_type\"])\n",
"data_Frame.head()"
]
},
{
"cell_type": "markdown",
"id": "c60cbf60-d904-4ee0-8f70-588bb109368b",
"metadata": {},
"source": [
"# Data preprocessing"
]
},
{
"cell_type": "markdown",
"id": "583e39c8-13ba-422e-9c39-9cf1c8d63d5b",
"metadata": {},
"source": [
"## Training set & validation set"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "38695a70-86e9-4dd0-b622-33e3762372eb",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"DataSet shape: (1034, 2)\n",
"Training set\n",
"------------\n",
"Dataframe shape: (827, 2)\n",
"Dataframe head:\n",
" genome_frequencies cancer_type\n",
"518 [25.0645, 0.1125, 56.3997, 3.3108, 1.6061, 12.... kirc\n",
"355 [32.6449, 2.1789, 63.4954, 6.3228, 2.109, 40.9... kirc\n",
"528 [46.024, 0.0, 85.8077, 7.2567, 2.1301, 9.6509,... kirc\n",
"445 [153.0064, 1.6403, 99.3267, 7.3736, 1.3668, 10... kirc\n",
"986 [65.5167, 18.2363, 77.2126, 5.0375, 2.4628, 21... kich\n",
"\n",
"Validation set\n",
"--------------\n",
"Dataframe shape: (207, 2)\n",
"Dataframe head:\n",
" genome_frequencies cancer_type\n",
"294 [50.8994, 0.4635, 131.5049, 5.7193, 3.103, 15.... kirp\n",
"453 [35.857, 0.1018, 94.5681, 5.2997, 1.9388, 17.6... kirc\n",
"638 [11.3865, 0.2313, 28.5961, 3.0169, 0.7851, 8.2... kirc\n",
"139 [41.6119, 0.2207, 55.4377, 4.4395, 0.884, 3.56... kirp\n",
"539 [63.1646, 18.8107, 63.2703, 4.6696, 0.9466, 5.... kirc\n"
]
}
],
"source": [
"import os\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"train_df, val_df = train_test_split(data_Frame, train_size=0.8, random_state=42)\n",
"\n",
"print(f\"DataSet shape: {data_Frame.shape}\")\n",
"print(f\"Training set{os.linesep}------------\")\n",
"print(f\"Dataframe shape: {train_df.shape}\")\n",
"print(f\"Dataframe head:{os.linesep}{train_df.head()}\")\n",
"print(\"\")\n",
"print(f\"Validation set{os.linesep}--------------\")\n",
"print(f\"Dataframe shape: {val_df.shape}\")\n",
"print(f\"Dataframe head:{os.linesep}{val_df.head()}\")"
]
},
{
"cell_type": "markdown",
"id": "4903244b-548f-4672-967d-1c62825b6fce",
"metadata": {},
"source": [
"## Building a custom PyTorch dataset"
]
},
{
"cell_type": "markdown",
"id": "7e333251-c4e7-41f0-a086-12a3d95b723f",
"metadata": {},
"source": [
"## Öffnen der Datei mit den Gesammelten Sequenzen"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "e2f78725-cda6-4e8d-9029-a4a31f6f9ab7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from torch.utils.data import Dataset\n",
"import torch\n",
"import pandas as pd\n",
"from sklearn.preprocessing import LabelEncoder\n",
"\n",
"class GenomeDataset(Dataset):\n",
" def __init__(self, dataframe):\n",
" self.dataframe = dataframe\n",
"\n",
" # Umwandlung der Genome Frequenzen in Tensoren\n",
" self.genome_frequencies = torch.tensor(dataframe['genome_frequencies'].tolist(), dtype=torch.float32)\n",
"\n",
" # Umwandlung der Krebsarten in numerische Werte\n",
" self.label_encoder = LabelEncoder()\n",
" self.cancer_types = torch.tensor(self.label_encoder.fit_transform(dataframe['cancer_type']), dtype=torch.long)\n",
"\n",
" def __getitem__(self, index):\n",
" # Rückgabe eines Tupels aus Genome Frequenzen und dem entsprechenden Krebstyp\n",
" return self.genome_frequencies[index], self.cancer_types[index]\n",
"\n",
" def __len__(self):\n",
" return len(self.dataframe)\n"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "aaa2c50c-c79e-4bca-812f-1a06c9f485d5",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Beispielhafte Verwendung\n",
"# Angenommen, df_train und df_valid sind Ihre Trainings- und Validierungsdaten\n",
"train_dataset = GenomeDataset(train_df)\n",
"valid_dataset = GenomeDataset(val_df)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "a7fb59af-bd06-42d4-acce-03266a85bf36",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Genome frequency from dataframe:\n",
"[2.50645e+01 1.12500e-01 5.63997e+01 ... 0.00000e+00 1.29000e-02\n",
" 2.47100e-01]\n",
"\n",
"Cancer type from dataframe: kirc\n",
"\n",
"Genome frequency from dataset:\n",
"tensor([2.5065e+01, 1.1250e-01, 5.6400e+01, ..., 0.0000e+00, 1.2900e-02,\n",
" 2.4710e-01])\n",
"\n",
"Cancer type from dataset: 1\n"
]
}
],
"source": [
"# Inspect the first item from the training dataframe\n",
"train_df_head = train_df.head(n=1)\n",
"train_df_genome_frequence =train_df_head.iloc[0][\"genome_frequencies\"]\n",
"train_df_cancer_type = train_df_head.iloc[0][\"cancer_type\"]\n",
"print(f\"Genome frequency from dataframe:{os.linesep}{train_df_genome_frequence}{os.linesep}\")\n",
"print(f\"Cancer type from dataframe: {train_df_cancer_type}{os.linesep}\")\n",
"\n",
"# Inspect the first item from the training dataset\n",
"datapoint_features, datapoint_label = train_dataset[0]\n",
"print(f\"Genome frequency from dataset:{os.linesep}{datapoint_features}{os.linesep}\")\n",
"print(f\"Cancer type from dataset: {datapoint_label}\")"
]
},
{
"cell_type": "markdown",
"id": "9199fdeb-0d48-44c2-8bec-db2a7d7cbd4d",
"metadata": {},
"source": [
"# Neuronales Netz Definition"
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "76b8eec8-d24b-4696-82bf-ebb286e7d1e7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import torch.optim as optim\n",
"from torch.utils.data import DataLoader\n",
"\n",
"# Definition des Modells\n",
"class SimpleNN(nn.Module):\n",
" def __init__(self, input_size, hidden_size, num_classes):\n",
" super(SimpleNN, self).__init__()\n",
" self.fc1 = nn.Linear(input_size, hidden_size)\n",
" self.relu = nn.ReLU()\n",
" self.fc2 = nn.Linear(hidden_size, num_classes)\n",
"\n",
" def forward(self, x):\n",
" out = self.fc1(x)\n",
" out = self.relu(out)\n",
" out = self.fc2(out)\n",
" return out"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "60789428-7d6e-4737-a83a-1138f6a650f7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Annahme: input_size ist die Länge Ihrer Genome-Frequenzen und num_classes ist die Anzahl der Krebsarten\n",
"model = SimpleNN(input_size=60660, hidden_size=100, num_classes=3)\n",
"\n",
"# Daten-Loader\n",
"train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)\n",
"valid_loader = DataLoader(dataset=valid_dataset, batch_size=64, shuffle=False)"
]
},
{
"cell_type": "code",
"execution_count": 58,
"id": "de6e81de-0096-443a-a0b6-90cddecf5f88",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Verlustfunktion und Optimierer\n",
"criterion = nn.CrossEntropyLoss()\n",
"optimizer = optim.Adam(model.parameters(), lr=0.001)\n",
"num_epochs = 70"
]
},
{
"cell_type": "code",
"execution_count": 59,
"id": "a5deb2ed-c685-4d80-bc98-d6dd27334d82",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch [1/70], Trainingsverlust: 0.8547, Validierungsverlust: 2.5101\n",
"Epoch [2/70], Trainingsverlust: 2.5368, Validierungsverlust: 5.2126\n",
"Epoch [3/70], Trainingsverlust: 1.9036, Validierungsverlust: 9.9862\n",
"Epoch [4/70], Trainingsverlust: 1.7232, Validierungsverlust: 3.0336\n",
"Epoch [5/70], Trainingsverlust: 0.4376, Validierungsverlust: 2.6327\n",
"Epoch [6/70], Trainingsverlust: 0.4104, Validierungsverlust: 3.7158\n",
"Epoch [7/70], Trainingsverlust: 0.8367, Validierungsverlust: 9.7647\n",
"Epoch [8/70], Trainingsverlust: 1.8869, Validierungsverlust: 3.4882\n",
"Epoch [9/70], Trainingsverlust: 1.6619, Validierungsverlust: 10.7534\n",
"Epoch [10/70], Trainingsverlust: 1.1150, Validierungsverlust: 11.3926\n",
"Epoch [11/70], Trainingsverlust: 1.5848, Validierungsverlust: 2.9740\n",
"Epoch [12/70], Trainingsverlust: 2.4469, Validierungsverlust: 9.1644\n",
"Epoch [13/70], Trainingsverlust: 1.4355, Validierungsverlust: 4.0663\n",
"Epoch [14/70], Trainingsverlust: 0.5209, Validierungsverlust: 2.9321\n",
"Epoch [15/70], Trainingsverlust: 0.1591, Validierungsverlust: 3.6580\n",
"Epoch [16/70], Trainingsverlust: 0.0267, Validierungsverlust: 2.7969\n",
"Epoch [17/70], Trainingsverlust: 0.0185, Validierungsverlust: 4.0949\n",
"Epoch [18/70], Trainingsverlust: 0.1175, Validierungsverlust: 2.6391\n",
"Epoch [19/70], Trainingsverlust: 0.0886, Validierungsverlust: 2.9849\n",
"Epoch [20/70], Trainingsverlust: 0.0122, Validierungsverlust: 3.4800\n",
"Epoch [21/70], Trainingsverlust: 0.0363, Validierungsverlust: 2.8900\n",
"Epoch [22/70], Trainingsverlust: 0.0973, Validierungsverlust: 6.5527\n",
"Epoch [23/70], Trainingsverlust: 0.6736, Validierungsverlust: 5.2661\n",
"Epoch [24/70], Trainingsverlust: 1.0836, Validierungsverlust: 5.7557\n",
"Epoch [25/70], Trainingsverlust: 0.8039, Validierungsverlust: 2.5515\n",
"Epoch [26/70], Trainingsverlust: 0.0618, Validierungsverlust: 2.4908\n",
"Epoch [27/70], Trainingsverlust: 0.0756, Validierungsverlust: 3.3003\n",
"Epoch [28/70], Trainingsverlust: 0.0285, Validierungsverlust: 3.6922\n",
"Epoch [29/70], Trainingsverlust: 0.0251, Validierungsverlust: 2.3733\n",
"Epoch [30/70], Trainingsverlust: 0.0284, Validierungsverlust: 2.6932\n",
"Epoch [31/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.4791\n",
"Epoch [32/70], Trainingsverlust: 0.0041, Validierungsverlust: 2.5808\n",
"Epoch [33/70], Trainingsverlust: 0.0005, Validierungsverlust: 2.5144\n",
"Epoch [34/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.3338\n",
"Epoch [35/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2991\n",
"Epoch [36/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2918\n",
"Epoch [37/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2900\n",
"Epoch [38/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2895\n",
"Epoch [39/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [40/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [41/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [42/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [43/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [44/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [45/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [46/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [47/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [48/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [49/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [50/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [51/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [52/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [53/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [54/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [55/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [56/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [57/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [58/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [59/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [60/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [61/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [62/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [63/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [64/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [65/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [66/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [67/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [68/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [69/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n",
"Epoch [70/70], Trainingsverlust: 0.0000, Validierungsverlust: 2.2894\n"
]
}
],
"source": [
"# Listen, um Verluste zu speichern\n",
"train_losses = []\n",
"valid_losses = []\n",
"\n",
"for epoch in range(num_epochs):\n",
" model.train()\n",
" train_loss = 0.0\n",
" for i, (inputs, labels) in enumerate(train_loader):\n",
" optimizer.zero_grad()\n",
" outputs = model(inputs)\n",
" loss = criterion(outputs, labels)\n",
" loss.backward()\n",
" optimizer.step()\n",
" train_loss += loss.item()\n",
"\n",
" # Durchschnittlicher Trainingsverlust\n",
" train_loss /= len(train_loader)\n",
" train_losses.append(train_loss)\n",
"\n",
" # Validierungsverlust\n",
" model.eval()\n",
" valid_loss = 0.0\n",
" with torch.no_grad():\n",
" for inputs, labels in valid_loader:\n",
" outputs = model(inputs)\n",
" loss = criterion(outputs, labels)\n",
" valid_loss += loss.item()\n",
"\n",
" # Durchschnittlicher Validierungsverlust\n",
" valid_loss /= len(valid_loader)\n",
" valid_losses.append(valid_loss)\n",
"\n",
" print(f'Epoch [{epoch+1}/{num_epochs}], Trainingsverlust: {train_loss:.4f}, Validierungsverlust: {valid_loss:.4f}')"
]
},
{
"cell_type": "code",
"execution_count": 60,
"id": "baf1caa8-d3d9-48e8-9339-81194521528d",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAHFCAYAAAAHcXhbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACJgUlEQVR4nO3dd3xT5f4H8M9Jmu7SBV1QKLNskD28AgqiIA7wulBB8AJXULjqvYILUIaouK84GSogclFERaaA/gRl71Fkr7JpoaUreX5/nJ40adZJcpI07ef9euWV9OTknCenofnyfb7P80hCCAEiIiKiIKULdAOIiIiIvMFghoiIiIIagxkiIiIKagxmiIiIKKgxmCEiIqKgxmCGiIiIghqDGSIiIgpqDGaIiIgoqDGYISIioqDGYCaISJKk6rZ27VqvzjNhwgRIkuTRa9euXatJGyozV9e3uLgYycnJ6NSpk8N9TCYTateujZYtW6o+r73fjTu/64yMDAwePNjp8UhbR48ehSRJmD17tk+Of/r0aUyYMAHbt293u01vvvkmACA6Otrqc6HIyMjAHXfcoVFLteXrz/LgwYNd/p3OyMhw+7izZ8+GJEk4evSoedu8efPwzjvvaNLuYBYS6AaQehs2bLD6+dVXX8WaNWvwyy+/WG1v2rSpV+d5/PHHcdttt3n02jZt2mDDhg1et6EqMxgMeOSRRzB9+nTs3bvX7rVctWoVTpw4gWeeecarc/F3XbWdPn0aEydOREZGBlq3bq3qNampqdiwYQPq1KkDAFizZg0SEhJ82Erf0/qz/NJLL2HEiBF2n5s9ezY+/vhj3HPPPW4ft2/fvtiwYQNSU1PN2+bNm4fdu3djzJgxnja3UmAwE0TK/0+9Ro0a0Ol0Tv8HDwD5+fmIjIxUfZ5atWqhVq1aHrWxWrVqLttDrg0dOhTTp0/HzJkzzf8DtjRz5kyEhobi4Ycf9uo8Fel3ff36dYSHh3ucFaxMjEYjSkpKAt0Mu8LCwqx+7+3btw9YW4QQKCgoQEREhFfH0fqzXL9+fdSvX99m+x9//IFZs2bhpptuwhtvvOH2cWvUqIEaNWpo0cRKh91MlUz37t3RvHlz/Prrr+jSpQsiIyMxZMgQAMCCBQtw6623IjU1FREREWjSpAnGjh2LvLw8q2PY63pQUsbLli1DmzZtEBERgcaNG2PmzJlW+9lL1w4ePBjR0dH466+/0KdPH0RHRyM9PR3PPPMMCgsLrV5/8uRJ3HvvvYiJiUFcXBwGDhyITZs22aTaDx8+jAceeABpaWkICwtDcnIybrnlFrfS5ZYGDx5sN+1r71pIkoRRo0bhyy+/RJMmTRAZGYlWrVrhxx9/tHn9Tz/9hNatWyMsLAx169a1G5jY06RJE3Tu3BlffvmlzZfalStX8P333+Ouu+5CYmIiNm/ejAceeAAZGRmIiIhARkYGHnzwQRw7dszleey9v+LiYvznP/9BSkoKIiMjceONN2Ljxo02r3WUmt+8eTPuvPNOJCQkIDw8HDfccAO++eYbq32UdPmKFSswZMgQ1KhRA5GRkSgsLPTZ7+L7779Hy5YtERYWhnr16uHdd9+1e8yFCxeiY8eOiI2NRWRkJOrVq2f+N3T+/HmEhobipZdesjn+/v37IUkS3nvvPfO27OxsDB8+HLVq1UJoaCjq1q2LiRMnWv1OlW6b119/HZMmTULdunURFhaGNWvW2JwDcO+z6uy9rF271hyIPPbYY+bujwkTJtg9r6NzAPa7PxTfffcdWrZsifDwcNSrV8/q+ihyc3Px7LPPom7duggNDUXNmjUxZswYm79Nyu/7o48+QpMmTRAWFoY5c+Y4bK8/PstqZWdnY8CAAahRowa++eYbhIRY5xJWrVqFW265BdWqVUNkZCS6du2K1atXW+1T/jp3794dP/30E44dO2bVhVUVMTNTCZ05cwYPP/ww/vOf/2DKlCnQ6eSY9eDBg+jTpw/GjBmDqKgo7N+/H9OmTcPGjRttuqrs2bFjB5555hmMHTsWycnJ+OyzzzB06FA0aNAAN910k9PXFhcX484778TQoUPxzDPP4Ndff8Wrr76K2NhYvPzyywCAvLw89OjRA5cuXcK0adPQoEEDLFu2DPfff7/N8fr06QOj0YjXX38dtWvXxoULF7B+/XpcuXLF/QvmgZ9++gmbNm3CK6+8gujoaLz++uu45557cODAAdSrVw8AsHr1atx1113o3Lkzvv76a3N7z549q+ocQ4cOxeOPP46ffvoJd911l3n7vHnzUFBQgKFDhwKQvwwzMzPxwAMPICEhAWfOnMGMGTPQvn177N27F9WrV3frvf3jH//AF198gWeffRa9evXC7t270b9/f1y9etXla9esWYPbbrsNHTt2xEcffYTY2Fh8/fXXuP/++5Gfn29TWzFkyBD07dsXX375JfLy8mAwGNxqK6Dud7Fs2TL0798fN910ExYsWICSkhK8+eabNr+LDRs24P7778f999+PCRMmIDw8HMeOHTP/+6hRowbuuOMOzJkzBxMnTjT/2wKAWbNmITQ0FAMHDgQgf3l16NABOp0OL7/8MurXr48NGzZg0qRJOHr0KGbNmmV17vfeew+NGjXCm2++iWrVqqFhw4ZuXwt33kubNm0wa9YsPPbYY3jxxRfRt29fAPA4U2fP9u3bMWbMGEyYMAEpKSmYO3cuRo8ejaKiIjz77LMA5Mxxt27dcPLkSTz//PNo2bIl9uzZg5dffhm7du3CqlWrrL6gFy9ejN9++w0vv/wyUlJSkJSU5PD8/vwsO1NcXIy///3vuHDhAtatW4fk5GSr57/66is8+uijuOuuuzBnzhwYDAZ8/PHH6N27N5YvX45bbrnF7nE//PBDDBs2DIcOHcJ3332nuj2VkqCgNWjQIBEVFWW1rVu3bgKAWL16tdPXmkwmUVxcLNatWycAiB07dpifGz9+vCj/0ahTp44IDw8Xx44dM2+7fv26SEhIEMOHDzdvW7NmjQAg1qxZY9VOAOKbb76xOmafPn1EZmam+ef//ve/AoD4+eefrfYbPny4ACBmzZolhBDiwoULAoB45513nL5HdwwaNEjUqVPHZru9awFAJCcni9zcXPO27OxsodPpxNSpU83bOnbsKNLS0sT169fN23Jzc0VCQoLNMe25evWqiI6OFnfeeafV9rZt24r09HRhNBrtvq6kpERcu3ZNREVFiXfffde83d7vpvz727dvnwAg/vWvf1kdc+7cuQKAGDRokNPjNW7cWNxwww2iuLjY6vV33HGHSE1NNbd51qxZAoB49NFHbdrvi99F+/btRXp6uigsLDRvu3r1qkhMTLQ65ptvvikAiCtXrticX7FkyRIBQKxYscK8raSkRKSlpYkBAwaYtw0fPlxER0db/ZuxPMeePXuEEEIcOXJEABD169cXRUVFVvsqzymffXeuj5r3smnTJpvjO2PvdyBE2e/zyJEj5m116tQRkiSJ7du3W+3bq1cvUa1aNZGXlyeEEGLq1KlCp9OJTZs2We33v//9TwAQS5cuNW8DIGJjY8WlS5dcttVfn2U1nnjiCQFAfPTRRzbP5eXliYSEBNGvXz+r7UajUbRq1Up06NDBvM3ede7bt6/dz0NVw26mSig+Ph4333yzzfbDhw/joYceQkpKCvR6PQwGA7p16wYA2Ldvn8vjtm7dGrVr1zb/HB4ejkaNGqnqzpAkCf369bPa1rJlS6vXrlu3DjExMTYFqQ8++KDVzwkJCahfvz7eeOMNvPXWW9i2bRtMJpPVPiaTCSUlJeab0Wh02UZ39OjRAzExMeafk5OTkZSUZH4/eXl52LRpE/r374/w8HDzfjExMTbXwZHo6Gjcd999WLp0qTmDsHv3bmzZsgWDBw82ZwWuXbuG5557Dg0aNEBISAhCQkIQHR2NvLw8Vb9XS0rXhpJdUNx33302afHy/vrrL+zfv9/8Wsvr36dPH5w5cwYHDhywes2AAQPcap89an4Xmzdvxt13343Q0FDzftHR0Ta/C6Xb5b777sM333yDU6dO2Zzv9ttvR0pKilVmZfny5Th9+rS5CwcAfvzxR/To0QNpaWlW1+L2228HIH/eLd15550eZaYcUfNefK1Zs2Zo1aqV1baHHnoIubm52Lp1KwD5OjVv3hytW7e2uk69e/e22/Vz8803Iz4+3uW5/f1ZdmT27Nn48MMPMWTIEAwfPtzm+fXr1+PSpUsYNGiQ1XlMJhNuu+02bNq0yaa7jWwxmKmELCvdFdeuXcPf/vY3/Pnnn5g0aRLWrl2LTZs24dtvvwUgF1+6kpiYaLMtLCxM1WsjIyOtvtSV1xYUFJh/vnjxok36FYDNNkmSsHr1avTu3Ruvv/462rRpgxo1auCpp54yp49feeUVGAwG881eMZ43XF2Ly5cvw2QyISUlxWY/e9scGTp0KEpKSvDll18CkAt/JUnCY489Zt7noYcewgcffIDHH38cy5cvx8aNG7Fp0ybUqFFD1e/G0sWLF+22MSQkxO57tqQEXM8++6zVtTcYDHjiiScAABcuXLB6jb3PqrvU/C6EEKo+WzfddBMWL16MkpISPProo6hVqxaaN2+O+fPnm/cJCQnBI488gu+++87crTl79mykpqaid+/e5v3Onj2LH374weZaNGvWDIBvroW778XXnH3+lc/a2bNnsXPnTpvrFBMTAyGEx9fJ359lezZv3ox//vOfaNeuHT788EOn57r33nttzjVt2jQIIXDp0iWX56rqWDNTCdkrAPvll19w+vRprF271pyNAeC3GhM1EhMT7RbnZWdn22yrU6cOPv/8cwBAVlYWvvnmG0yYMAFFRUX46KOPMGzYMKs5LsLCwpyeOzw83KYYGVD3B8ue+Ph4SJJkt+32tjnSpUsXNGnSBLNmzcLo0aPx1Vdf4eabb0bdunUBADk5Ofjxxx8xfvx4jB071vy6wsJCj/4AKn/ks7OzUbNmTfP2kpIS85eDI0ptzrhx49C/f3+7+2RmZlr9bO+z6qvfhb1aJXu/i7vuugt33XUXCgsL8ccff2Dq1Kl46KGHkJGRgc6dOwOQC2bfeOMNcw3FkiVLMGbMGOj1evNxqlevjpYtW2Ly5Ml225WWlmb1s9rCTXeuj5r34g7lPySFhYVW/6Yc/W6cff6Vz1r16tURERFhM5hAUb7mS+118vdnubzz58+jf//+iI6OxqJFixz+DVLO9f777zscUWUvECdrDGaqCOUPQPl/UB9//HEgmmNXt27d8M033+Dnn382p+IB4Ouvv3b6ukaNGuHFF1/EokWLzKnrtLQ0my8LZzIyMnDu3DmcPXvW/IejqKgIy5cv9+CdAFFRUejQoQO+/fZbvPHGG+YvgatXr+KHH35w61hDhgzBv//9b7z44os4f/68VVeGJEkQQtj8Xj/77DOPuta6d+8OAJg7dy7atm1r3v7NN9+4HCqcmZmJhg0bYseOHZgyZYrb51b44nfRrl07LF68GG+++aa5q+natWt2Rz0pwsLC0K1bN8TFxWH58uXYtm2bOQBo0qQJOnbsiFmzZsFoNKKwsNAqWwYAd9xxB5YuXYr69eur6hZRy5Pr4+i9KJ8btRk8ZRTVzp07rYZkO/pM79mzBzt27LDqapo3bx5iYmLQpk0bAPJ1mjJlChITE81BuhYC+VkuKSnB3//+d5w+fRorVqyw6p4vr2vXroiLi8PevXsxatQot8+lNjte2TGYqSK6dOmC+Ph4jBgxAuPHj4fBYMDcuXOxY8eOQDfNbNCgQXj77bfx8MMPY9KkSWjQoAF+/vln8x9ppUZk586dGDVqFP7+97+jYcOGCA0NxS+//IKdO3daZSfccf/99+Pll1/GAw88gH//+98oKCjAe++951WtzauvvorbbrsNvXr1wjPPPAOj0Yhp06YhKirKrazJo48+iueffx5vvPEG4uLirP6nWK1aNfOcFdWrV0dGRgbWrVuHzz//HHFxcW63uUmTJnj44YfxzjvvwGAwoGfPnti9e7d5hI0rH3/8MW6//Xb07t0bgwcPRs2aNXHp0iXs27cPW7duxcKFC10ewxe/i1deeQV9+/ZF7969MXr0aBiNRrzxxhuIjo62+l28/PLLOHnyJG655RbUqlULV65cwbvvvmtVX6ZQaiBOnz6NLl262PxP/ZVXXsHKlSvRpUsXPPXUU8jMzERBQQGOHj2KpUuX4qOPPvJo5JDa66PmvdSvXx8RERGYO3cumjRpgujoaKf/EejTpw8SEhIwdOhQvPLKKwgJCcHs2bNx4sQJu/unpaXhzjvvxIQJE5CamoqvvvoKK1euxLRp08xzX40ZMwaLFi3CTTfdhH/9619o2bIlTCYTjh8/jhUrVuCZZ55Bx44d3b5Ogfws//vf/8a6deswcOBAREZG4o8//rC7X6dOnRAdHY33338fgwYNwqVLl3DvvfciKSkJ58+fx44dO3D+/HnMmDHD4blatGiBb7/9FjNmzEDbtm2h0+nQrl071xeosgls/TF5w9FopmbNmtndf/369aJz584iMjJS1KhRQzz++ONi69atNqMZHI1m6tu3r80xu3XrJrp162b+2dFopvLtdHSe48ePi/79+4vo6GgRExMjBgwYIJYuXSoAiO+//14IIcTZs2fF4MGDRePGjUVUVJSIjo4WLVu2FG+//bYoKSmx+97VWLp0qWjdurWIiIgQ9erVEx988IHDETQjR460eX2dOnWsRkgIIY98admypQgNDRW1a9cWr732msMRIc7cc889AoB44oknbJ47efKkGDBggIiPjxcxMTHitttuE7t377Zpj5rRTEIIUVhYKJ555hmRlJQkwsPDRadOncSGDRtUHU8IIXbs2CHuu+8+kZSUJAwGg0hJSRE333yz1UgOZVRG+REsCl/8Lr777jvRokULq9/FU089JeLj4837/Pjjj+L2228XNWvWFKGhoSIpKUn06dNH/PbbbzbnyMnJEREREQKA+PTTT+2+j/Pnz4unnnpK1K1bVxgMBpGQkCDatm0rXnjhBXHt2jUhRNmIpTfeeMPm9fZGM6m9Pmrfy/z580Xjxo2FwWAQAMT48ePtvhfFxo0bRZcuXURUVJSoWbOmGD9+vPjss8/sjmbq27ev+N///ieaNWsmQkNDRUZGhnjrrbdsjnnt2jXx4osviszMTBEaGipiY2NFixYtxL/+9S+RnZ1t3s/R79sRf3yW7alTp44A4PJmad26daJv374iISFBGAwGUbNmTdG3b1+xcOFC8z72RjNdunRJ3HvvvSIuLk5IkuT235bKQhJCCF8HTETemDJlCl588UUcP35c0zkwqGorLi5G69atUbNmTaxYsSLQzSEiL7CbiSqUDz74AADQuHFjFBcX45dffsF7772Hhx9+mIEMeWXo0KHo1asXUlNTkZ2djY8++gj79u3Du+++G+imEZGXGMxQhRIZGYm3334bR48eRWFhIWrXro3nnnsOL774YqCbRkHu6tWrePbZZ3H+/HkYDAa0adMGS5cuRc+ePQPdNCLyEruZiIiIKKhx0jwiIiIKagxmiIiIKKgxmCEiIqKgVukLgE0mE06fPo2YmBjV02ATERFRYAkhcPXqVaSlpZknTXWk0gczp0+fRnp6eqCbQURERB44ceKEy6k5Kn0wExMTA0C+GGqmsCYiIqLAy83NRXp6uvl73JlKH8woXUvVqlVjMENERBRk1JSIsACYiIiIghqDGSIiIgpqDGaIiIgoqFX6mhkiosrEaDSiuLg40M0g8prBYIBer9fkWAxmiIiCgBAC2dnZuHLlSqCbQqSZuLg4pKSkeD0PHIMZIqIgoAQySUlJiIyM5CSgFNSEEMjPz8e5c+cAAKmpqV4dj8EMEVEFZzQazYFMYmJioJtDpImIiAgAwLlz55CUlORVlxMLgImIKjilRiYyMjLALSHSlvKZ9rYOjMEMEVGQYNcSVTZafaYZzBAREVFQYzBDRERBpXv37hgzZozq/Y8ePQpJkrB9+3aftcmfJEnC4sWLA92MCoXBDBER+YQkSU5vgwcP9ui43377LV599VXV+6enp+PMmTNo3ry5R+erzNauXQtJkoJ+yD9HM5FrQgCmEkBvCHRLiCiInDlzxvx4wYIFePnll3HgwAHzNmU0i6K4uBgGg+u/MwkJCW61Q6/XIyUlxa3XVERFRUUIDQ0NdDMqJGZmyLX17wGTkoETGwPdEiIKIikpKeZbbGwsJEky/1xQUIC4uDh888036N69O8LDw/HVV1/h4sWLePDBB1GrVi1ERkaiRYsWmD9/vtVxy3czZWRkYMqUKRgyZAhiYmJQu3ZtfPLJJ+bny3czKdmI1atXo127doiMjESXLl2sAi0AmDRpEpKSkhATE4PHH38cY8eORevWrc3Pr127Fh06dEBUVBTi4uLQtWtXHDt2DAcOHIAkSdi/f7/V8d566y1kZGRACAEA2Lt3L/r06YPo6GgkJyfjkUcewYULF6ze56hRo/D000+jevXq6NWrl801tpdZ2b59OyRJwtGjRwEAx44dQ79+/RAfH4+oqCg0a9YMS5cuxdGjR9GjRw8AQHx8vFfZskBjMEPOGUuA9e8DwshghqgCEUIgv6jE7zfli1grzz33HJ566ins27cPvXv3RkFBAdq2bYsff/wRu3fvxrBhw/DII4/gzz//dHqc6dOno127dti2bRueeOIJ/POf/7QJJsp74YUXMH36dGzevBkhISEYMmSI+bm5c+di8uTJmDZtGrZs2YLatWtjxowZ5udLSkpw9913o1u3bti5cyc2bNiAYcOGQZIkZGZmom3btpg7d67V+ebNm4eHHnoIkiThzJkz6NatG1q3bo3Nmzdj2bJlOHv2LO677z6r18yZMwchISH4/fff8fHHH6u9rFZGjhyJwsJC/Prrr9i1axemTZuG6OhopKenY9GiRQCAAwcO4MyZM3j33Xc9OkegsZuJnDv6G5B3Xn5sLAxsW4jI7HqxEU1fXu738+59pTciQ7X76hgzZgz69+9vte3ZZ581P37yySexbNkyLFy4EB07dnR4nD59+uCJJ54AIAdIb7/9NtauXYvGjRs7fM3kyZPRrVs3AMDYsWPRt29fFBQUIDw8HO+//z6GDh2Kxx57DADw8ssvY8WKFbh27RoAIDc3Fzk5ObjjjjtQv359AECTJk3Mxx44cCA++OADc21PVlYWtmzZgi+++AIAMGPGDLRp0wZTpkwxv2bmzJlIT09HVlYWGjVqBABo0KABXn/9dWeX0KXjx49jwIABaNGiBQCgXr165ueULrukpCTExcV5dZ5AYmaGnNv9v7LHRi5uR0TaateundXPRqMRkydPRsuWLZGYmIjo6GisWLECx48fd3qcli1bmh8r3VnKVPlqXqNMp6+85sCBA+jQoYPV/pY/JyQkYPDgwejduzf69euHd99916pG6IEHHsCxY8fwxx9/AJAzPa1bt0bTpk0BAFu2bMGaNWsQHR1tvimB16FDhxxeH0889dRTmDRpErp27Yrx48dj586dXh+zomFmhhwrKQT2/mD9MxFVCBEGPfa+0jsg59VSVFSU1c/Tp0/H22+/jXfeeQctWrRAVFQUxowZ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BcLDwx3uV9mvw+23325+3KJFC3Tu3Bn169fHnDlz0KlTJwCV/xqYTCa0a9cOU6ZMAQDccMMN2LNnD2bMmIFHH33UvF9lvw6Kzz//HLfffjvS0tKstvvj/TMz46bq1atDr9fbRJXnzp2ziT6rCmUEQ1W4Jk8++SSWLFmCNWvWoFatWubtVekahIaGokGDBmjXrh2mTp2KVq1a4d13360y12DLli04d+4c2rZti5CQEISEhGDdunV47733EBISYn6vlf06lBcVFYUWLVrg4MGDVeazkJqaiqZNm1pta9KkCY4fPw6gav1dOHbsGFatWoXHH3/cvM2f75/BjJtCQ0PRtm1brFy50mr7ypUr0aVLlwC1KrDq1q2LlJQUq2tSVFSEdevWVZprIoTAqFGj8O233+KXX35B3bp1rZ6vCtfAESEECgsLq8w1uOWWW7Br1y5s377dfGvXrh0GDhyI7du3o169elXiOpRXWFiIffv2ITU1tcp8Frp27WozRUNWVhbq1KkDoGr9XZg1axaSkpLQt29f8za/vn9Ny4mrCGVo9ueffy727t0rxowZI6KiosTRo0cD3TSfuXr1qti2bZvYtm2bACDeeustsW3bNvNw9Ndee03ExsaKb7/9VuzatUs8+OCDlWr44T//+U8RGxsr1q5dazUMMT8/37xPZb8GQggxbtw48euvv4ojR46InTt3iueff17odDqxYsUKIUTVuAb2WI5mEqJqXIdnnnlGrF27Vhw+fFj88ccf4o477hAxMTHmv4NV4Rps3LhRhISEiMmTJ4uDBw+KuXPnisjISPHVV1+Z96kK18FoNIratWuL5557zuY5f71/BjMe+u9//yvq1KkjQkNDRZs2bcxDdCurNWvWCAA2t0GDBgkh5CGI48ePFykpKSIsLEzcdNNNYteuXYFttIbsvXcAYtasWeZ9Kvs1EEKIIUOGmD/3NWrUELfccos5kBGialwDe8oHM1XhOijzhRgMBpGWlib69+8v9uzZY36+KlwDIYT44YcfRPPmzUVYWJho3Lix+OSTT6yerwrXYfny5QKAOHDggM1z/nr/khBCaJvrISIiIvIf1swQERFRUGMwQ0REREGNwQwREREFNQYzREREFNQYzBAREVFQYzBDREREQY3BDBEREQU1BjNEVOlIkoTFixcHuhlE5CcMZohIU4MHD4YkSTa32267LdBNI6JKKiTQDSCiyue2227DrFmzrLaFhYUFqDVEVNkxM0NEmgsLC0NKSorVLT4+HoDcBTRjxgzcfvvtiIiIQN26dbFw4UKr1+/atQs333wzIiIikJiYiGHDhuHatWtW+8ycORPNmjVDWFgYUlNTMWrUKKvnL1y4gHvuuQeRkZFo2LAhlixZYvX83r170adPH0RHRyM5ORmPPPIILly4YH6+e/fueOqpp/Cf//wHCQkJSElJwYQJEzS8SkSkFQYzROR3L730EgYMGIAdO3bg4YcfxoMPPoh9+/YBAPLz83HbbbchPj4emzZtwsKFC7Fq1SqrYGXGjBkYOXIkhg0bhl27dmHJkiVo0KCB1TkmTpyI++67Dzt37kSfPn0wcOBAXLp0CQBw5swZdOvWDa1bt8bmzZuxbNkynD17Fvfdd5/VMebMmYOoqCj8+eefeP311/HKK69g5cqVPr46ROQ2zZeuJKIqbdCgQUKv14uoqCir2yuvvCKEkFcgHzFihNVrOnbsKP75z38KIYT45JNPRHx8vLh27Zr5+Z9++knodDqRnZ0thBAiLS1NvPDCCw7bAEC8+OKL5p+vXbsmJEkSP//8sxBCiJdeeknceuutVq85ceKE1cq/3bp1EzfeeKPVPu3btxfPPfecW9eDiHyPNTNEpLkePXpgxowZVtsSEhLMjzt37mz1XOfOnbF9+3YAwL59+9CqVStERUWZn+/atStMJhMOHDgASZJw+vRp3HLLLU7b0LJlS/PjqKgoxMTE4Ny5cwCALVu2YM2aNYiOjrZ53aFDh9CoUSObYwBAamqq+RhEVHEwmCEizUVFRdl0+7giSRIAQAhhfmxvn4iICFXHMxgMNq81mUwAAJPJhH79+mHatGk2r0tNTVV1DCKqOFgzQ0R+98cff9j83LhxYwBA06ZNsX37duTl5Zmf//3336HT6dCoUSPExMQgIyMDq1ev9vj8bdq0wZ49e5CRkYEGDRpY3SwzQkQUHBjMEJHmCgsLkZ2dbXWzHCm0cOFCzJw5E1lZWRg/fjw2btxoLvAdOHAgwsPDMWjQIOzevRtr1qzBk08+iUceeQTJyckAgAkTJmD69Ol47733cPDgQWzduhXvv/++6vaNHDkSly5dwoMPPoiNGzfi8OHDWLFiBYYMGQKj0ajtxSAin2M3ExFpbtmyZVbdNQCQmZmJ/fv3A5BHGn399dd44oknkJKSgrlz56Jp06YAgMjISCxfvhyjR49G+/btERkZiQEDBuCtt94yH2vQoEEoKCjA22+/jWeffRbVq1fHvffeq7p9aWlp+P333/Hcc8+hd+/eKCwsRJ06dXDbbbdBp+P/8YiCjSSEEIFuBBFVHZIk4bvvvsPdd98d6KYQUSXB/4IQERFRUGMwQ0REREGNNTNE5Ffs2SYirTEzQ0REREGNwQwREREFNQYzREREFNQYzBAREVFQYzBDREREQY3BDBEREQU1BjNEREQU1BjMEBERUVBjMENERERB7f8ByhlshpjHkf4AAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"plt.plot(train_losses, label='Trainingsverlust')\n",
"plt.plot(valid_losses, label='Validierungsverlust')\n",
"plt.xlabel('Epochen')\n",
"plt.ylabel('Verlust')\n",
"plt.title('Trainings- und Validierungsverlust über die Zeit')\n",
"plt.legend()\n",
"plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "8e339354-a7cc-4e8a-9323-4be41ef62117",
"metadata": {},
"outputs": [],
"source": [
"# Laden der 'kirp' Liste aus der Pickle-Datei\n",
"with open('rick.pickle', 'rb') as f:\n",
" rick = pickle.load(f)\n"
]
},
{
"cell_type": "markdown",
"id": "be10a487-728e-4953-a081-9103d485378c",
"metadata": {},
"source": [
"## Hauptkomponentenanalyse (PCA)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "088db0b3-8c33-41ff-a543-1b1e50c5e589",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Transformierte Daten: [[-6.02552113e+01 4.57642675e+01 1.11957079e+02 ... 2.58331825e+00\n",
" 9.99342571e-01 -2.77477317e-01]\n",
" [-1.64705386e+01 9.03712725e+00 1.04837673e+01 ... 4.06859167e+00\n",
" 2.01083350e+00 1.49404086e+00]\n",
" [ 7.52348753e+00 -1.55853934e+01 -4.76301782e+01 ... -7.87604764e+00\n",
" -7.56801224e-02 8.37028680e+00]\n",
" ...\n",
" [-2.72012678e+01 4.44526098e+00 2.60063820e+01 ... 3.08321694e-01\n",
" 2.28939485e+00 -7.14920382e+00]\n",
" [-3.48027066e+01 2.27021639e+01 5.51486742e+01 ... -1.77955416e+01\n",
" 6.24722406e+00 2.32101665e+01]\n",
" [-3.98223613e+01 1.88534866e+01 5.32794498e+01 ... -1.45806809e+00\n",
" 1.18270903e+01 -2.84291311e+00]]\n",
"Varianz erklärt durch jede Komponente: [0.15056597 0.0997506 0.06070173 0.03658789 0.03530275 0.0263503\n",
" 0.02322747 0.01705354 0.01534278 0.01281486 0.01116959 0.0107472\n",
" 0.00989894 0.00906208 0.00871621 0.00813403 0.0074718 0.00708769\n",
" 0.00667045 0.00633275 0.00579241 0.00556758 0.00532382 0.00519289\n",
" 0.00476404 0.00472014 0.00457837 0.00414668 0.00399478 0.00380604\n",
" 0.00362433 0.00349278 0.00336446 0.00323228 0.00310834 0.00300595\n",
" 0.00297408 0.00285178 0.00280688 0.00273987 0.00268256 0.00263102\n",
" 0.00250513 0.00248987 0.0024505 0.0023979 0.00235971 0.00218554\n",
" 0.00217143 0.00212775 0.00210793 0.00205678 0.00202224 0.00200579\n",
" 0.00194754 0.00189606 0.00187714 0.00184969 0.00180133 0.00178537\n",
" 0.00176576 0.00172542 0.00168211 0.00167483 0.00162565 0.00159444\n",
" 0.00158667 0.00155982 0.00155534 0.00151929 0.00149558 0.00147549\n",
" 0.00146982 0.00146262 0.00143338 0.00142085 0.00140628 0.00139744\n",
" 0.00136563 0.00136169 0.00134972 0.00132027 0.00129168 0.00127963\n",
" 0.00126629 0.0012562 0.00123608 0.00122899 0.0012035 0.0011899\n",
" 0.00118094 0.00117162 0.00116552 0.00114295 0.00112631 0.00111896\n",
" 0.00110193 0.00109004 0.00108523 0.00106574 0.00106381 0.001051\n",
" 0.00104179 0.00103669 0.00103248 0.00101669 0.00100527 0.00099315\n",
" 0.00097478 0.00096486 0.00096244 0.00094792 0.00094463 0.00093107\n",
" 0.00092485 0.00090851 0.00089848 0.00089134 0.00087855 0.00087068\n",
" 0.00086397 0.00085563 0.00084342 0.00083406 0.00083064 0.00081791\n",
" 0.00080368 0.00080183 0.00079167 0.00079072 0.00078868 0.00078028\n",
" 0.00077115 0.00076662 0.00076043 0.00075196 0.0007447 0.0007332\n",
" 0.0007252 0.00072345 0.00071902 0.00070594 0.00070125 0.00069603\n",
" 0.00069029 0.00068619 0.00068012 0.00067224 0.00066615 0.00066017]\n"
]
}
],
"source": [
"import numpy as np\n",
"from sklearn.decomposition import PCA\n",
"from sklearn.preprocessing import StandardScaler\n",
"\n",
"# Angenommen, X ist Ihr Datensatz\n",
"# X = ...\n",
"X = rick\n",
"\n",
"# Standardisieren der Daten\n",
"scaler = StandardScaler()\n",
"X_scaled = scaler.fit_transform(X)\n",
"\n",
"# Erstellen des PCA-Objekts\n",
"pca = PCA(n_components=150) # Angenommen, Sie möchten 150 Hauptkomponenten behalten\n",
"\n",
"# Durchführen der PCA\n",
"X_pca = pca.fit_transform(X_scaled)\n",
"\n",
"# Die resultierenden Hauptkomponenten\n",
"print(\"Transformierte Daten:\", X_pca)\n",
"\n",
"# Variance Ratio für jede Komponente\n",
"print(\"Varianz erklärt durch jede Komponente:\", pca.explained_variance_ratio_)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b11bbe20-0494-4e7a-83ff-3cb0bfa82f3b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}