\n",
"مجموعه داده گربه در مقابل سگ برای این مثال استفاده شده است. این مجموعه داده در چالش بینایی کامپیوتر اواخر سال ۲۰۱۳ توسط سایت Kaggle.com در دسترس عموم قرار گرفت.\n",
" \n",
"از قبل از سال ۲۰۱۳ استفاده از شبکه های کانولوشنالی خیلی رایج نبود.\n",
"مجموعه داده در آدرس زیر قابل دانلود است.\n",
"
\n",
"\n",
"`https://www.kaggle.com/c/dogs-vs-cats/data`\n",
"\n",
"\n",
"\n",
"![cats_vs_dogs_samples](https://s3.amazonaws.com/book.keras.io/img/ch5/cats_vs_dogs_samples.jpg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Unsurprisingly, the cats vs. dogs Kaggle competition in 2013 was won by entrants who used convnets. The best entries could achieve up to \n",
"95% accuracy. In our own example, we will get fairly close to this accuracy (in the next section), even though we will be training our \n",
"models on less than 10% of the data that was available to the competitors.\n",
"This original dataset contains 25,000 images of dogs and cats (12,500 from each class) and is 543MB large (compressed). After downloading \n",
"and uncompressing it, we will create a new dataset containing three subsets: a training set with 1000 samples of each class, a validation \n",
"set with 500 samples of each class, and finally a test set with 500 samples of each class.\n",
"\n",
"Here are a few lines of code to do this:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import os, shutil"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# The path to the directory where the original\n",
"# dataset was uncompressed\n",
"original_dataset_dir = 'D:/dataset/catDog/train'\n",
"\n",
"# The directory where we will\n",
"# store our smaller dataset\n",
"base_dir = 'D:/dataset/catDog/catVsdog'\n",
"os.mkdir(base_dir)\n",
"\n",
"# Directories for our training,\n",
"# validation and test splits\n",
"train_dir = os.path.join(base_dir, 'train')\n",
"os.mkdir(train_dir)\n",
"validation_dir = os.path.join(base_dir, 'validation')\n",
"os.mkdir(validation_dir)\n",
"test_dir = os.path.join(base_dir, 'test')\n",
"os.mkdir(test_dir)\n",
"\n",
"# Directory with our training cat pictures\n",
"train_cats_dir = os.path.join(train_dir, 'cats')\n",
"os.mkdir(train_cats_dir)\n",
"\n",
"# Directory with our training dog pictures\n",
"train_dogs_dir = os.path.join(train_dir, 'dogs')\n",
"os.mkdir(train_dogs_dir)\n",
"\n",
"# Directory with our validation cat pictures\n",
"validation_cats_dir = os.path.join(validation_dir, 'cats')\n",
"os.mkdir(validation_cats_dir)\n",
"\n",
"# Directory with our validation dog pictures\n",
"validation_dogs_dir = os.path.join(validation_dir, 'dogs')\n",
"os.mkdir(validation_dogs_dir)\n",
"\n",
"# Directory with our validation cat pictures\n",
"test_cats_dir = os.path.join(test_dir, 'cats')\n",
"os.mkdir(test_cats_dir)\n",
"\n",
"# Directory with our validation dog pictures\n",
"test_dogs_dir = os.path.join(test_dir, 'dogs')\n",
"os.mkdir(test_dogs_dir)\n",
"\n",
"# Copy first 1000 cat images to train_cats_dir\n",
"fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]\n",
"for fname in fnames:\n",
" src = os.path.join(original_dataset_dir, fname)\n",
" dst = os.path.join(train_cats_dir, fname)\n",
" shutil.copyfile(src, dst)\n",
"\n",
"# Copy next 500 cat images to validation_cats_dir\n",
"fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]\n",
"for fname in fnames:\n",
" src = os.path.join(original_dataset_dir, fname)\n",
" dst = os.path.join(validation_cats_dir, fname)\n",
" shutil.copyfile(src, dst)\n",
" \n",
"# Copy next 500 cat images to test_cats_dir\n",
"fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]\n",
"for fname in fnames:\n",
" src = os.path.join(original_dataset_dir, fname)\n",
" dst = os.path.join(test_cats_dir, fname)\n",
" shutil.copyfile(src, dst)\n",
" \n",
"# Copy first 1000 dog images to train_dogs_dir\n",
"fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]\n",
"for fname in fnames:\n",
" src = os.path.join(original_dataset_dir, fname)\n",
" dst = os.path.join(train_dogs_dir, fname)\n",
" shutil.copyfile(src, dst)\n",
" \n",
"# Copy next 500 dog images to validation_dogs_dir\n",
"fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]\n",
"for fname in fnames:\n",
" src = os.path.join(original_dataset_dir, fname)\n",
" dst = os.path.join(validation_dogs_dir, fname)\n",
" shutil.copyfile(src, dst)\n",
" \n",
"# Copy next 500 dog images to test_dogs_dir\n",
"fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]\n",
"for fname in fnames:\n",
" src = os.path.join(original_dataset_dir, fname)\n",
" dst = os.path.join(test_dogs_dir, fname)\n",
" shutil.copyfile(src, dst)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##
برای بررسی صحت انجام کار تعداد تصاویرآموزشی/آزمون/توسعه را بررسی میکنیم.
\n",
"\n",
"Since we are attacking a binary classification problem, we are ending the network with a single unit (a `Dense` layer of size 1) and a \n",
"`sigmoid` activation. This unit will encode the probability that the network is looking at one class or the other."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"from keras import layers\n",
"from keras import models\n",
"\n",
"model = models.Sequential()\n",
"model.add(layers.Conv2D(32, (3, 3), activation='relu',\n",
" input_shape=(150, 150, 3)))\n",
"model.add(layers.MaxPooling2D((2, 2)))\n",
"model.add(layers.Conv2D(64, (3, 3), activation='relu'))\n",
"model.add(layers.MaxPooling2D((2, 2)))\n",
"model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n",
"model.add(layers.MaxPooling2D((2, 2)))\n",
"model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n",
"model.add(layers.MaxPooling2D((2, 2)))\n",
"model.add(layers.Flatten())\n",
"model.add(layers.Dense(512, activation='relu'))\n",
"model.add(layers.Dense(1, activation='sigmoid'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's take a look at how the dimensions of the feature maps change with every successive layer:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"conv2d_5 (Conv2D) (None, 148, 148, 32) 896 \n",
"_________________________________________________________________\n",
"max_pooling2d_5 (MaxPooling2 (None, 74, 74, 32) 0 \n",
"_________________________________________________________________\n",
"conv2d_6 (Conv2D) (None, 72, 72, 64) 18496 \n",
"_________________________________________________________________\n",
"max_pooling2d_6 (MaxPooling2 (None, 36, 36, 64) 0 \n",
"_________________________________________________________________\n",
"conv2d_7 (Conv2D) (None, 34, 34, 128) 73856 \n",
"_________________________________________________________________\n",
"max_pooling2d_7 (MaxPooling2 (None, 17, 17, 128) 0 \n",
"_________________________________________________________________\n",
"conv2d_8 (Conv2D) (None, 15, 15, 128) 147584 \n",
"_________________________________________________________________\n",
"max_pooling2d_8 (MaxPooling2 (None, 7, 7, 128) 0 \n",
"_________________________________________________________________\n",
"flatten_2 (Flatten) (None, 6272) 0 \n",
"_________________________________________________________________\n",
"dense_3 (Dense) (None, 512) 3211776 \n",
"_________________________________________________________________\n",
"dense_4 (Dense) (None, 1) 513 \n",
"=================================================================\n",
"Total params: 3,453,121\n",
"Trainable params: 3,453,121\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"model.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For our compilation step, we'll go with the `RMSprop` optimizer as usual. Since we ended our network with a single sigmoid unit, we will \n",
"use binary crossentropy as our loss (as a reminder, check out the table in Chapter 4, section 5 for a cheatsheet on what loss function to \n",
"use in various situations)."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"from keras import optimizers\n",
"\n",
"model.compile(loss='binary_crossentropy',\n",
" optimizer=optimizers.RMSprop(lr=1e-4),\n",
" metrics=['acc'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##
پیش پردازش داده (Data preprocessing)
\n",
"\n",
"* Read the picture files.\n",
"* Decode the JPEG content to RGB grids of pixels.\n",
"* Convert these into floating point tensors.\n",
"* Rescale the pixel values (between 0 and 255) to the [0, 1] interval (as you know, neural networks prefer to deal with small input values).\n",
"\n",
"It may seem a bit daunting, but thankfully Keras has utilities to take care of these steps automatically. Keras has a module with image \n",
"processing helper tools, located at `keras.preprocessing.image`. In particular, it contains the class `ImageDataGenerator` which allows to \n",
"quickly set up Python generators that can automatically turn image files on disk into batches of pre-processed tensors. This is what we \n",
"will use here.\n",
"\n",
"
\n",
" اطلاعات بیشتر در مستندات Keras :\n",
"
\n",
"\n",
"`https://keras.io/preprocessing/image/`"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 2000 images belonging to 2 classes.\n",
"Found 1000 images belonging to 2 classes.\n"
]
}
],
"source": [
"from keras.preprocessing.image import ImageDataGenerator\n",
"\n",
"# All images will be rescaled by 1./255\n",
"train_datagen = ImageDataGenerator(rescale=1./255)\n",
"test_datagen = ImageDataGenerator(rescale=1./255)\n",
"\n",
"train_generator = train_datagen.flow_from_directory(\n",
" # This is the target directory\n",
" train_dir,\n",
" # All images will be resized to 150x150\n",
" target_size=(150, 150),\n",
" batch_size=20,\n",
" # Since we use binary_crossentropy loss, we need binary labels\n",
" class_mode='binary')\n",
"\n",
"validation_generator = test_datagen.flow_from_directory(\n",
" validation_dir,\n",
" target_size=(150, 150),\n",
" batch_size=20,\n",
" class_mode='binary')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's take a look at the output of one of these generators: it yields batches of 150x150 RGB images (shape `(20, 150, 150, 3)`) and binary \n",
"labels (shape `(20,)`). 20 is the number of samples in each batch (the batch size). Note that the generator yields these batches \n",
"indefinitely: it just loops endlessly over the images present in the target folder. For this reason, we need to `break` the iteration loop \n",
"at some point."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"data batch shape: (20, 150, 150, 3)\n",
"labels batch shape: (20,)\n"
]
}
],
"source": [
"for data_batch, labels_batch in train_generator:\n",
" print('data batch shape:', data_batch.shape)\n",
" print('labels batch shape:', labels_batch.shape)\n",
" break"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's fit our model to the data using the generator. We do it using the `fit_generator` method, the equivalent of `fit` for data generators \n",
"like ours. It expects as first argument a Python generator that will yield batches of inputs and targets indefinitely, like ours does. \n",
"Because the data is being generated endlessly, the generator needs to know example how many samples to draw from the generator before \n",
"declaring an epoch over. This is the role of the `steps_per_epoch` argument: after having drawn `steps_per_epoch` batches from the \n",
"generator, i.e. after having run for `steps_per_epoch` gradient descent steps, the fitting process will go to the next epoch. In our case, \n",
"batches are 20-sample large, so it will take 100 batches until we see our target of 2000 samples.\n",
"\n",
"When using `fit_generator`, one may pass a `validation_data` argument, much like with the `fit` method. Importantly, this argument is \n",
"allowed to be a data generator itself, but it could be a tuple of Numpy arrays as well. If you pass a generator as `validation_data`, then \n",
"this generator is expected to yield batches of validation data endlessly, and thus you should also specify the `validation_steps` argument, \n",
"which tells the process how many batches to draw from the validation generator for evaluation."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/30\n",
"100/100 [==============================] - 16s 163ms/step - loss: 0.6893 - acc: 0.5310 - val_loss: 0.6687 - val_acc: 0.6220\n",
"Epoch 2/30\n",
"100/100 [==============================] - 12s 121ms/step - loss: 0.6580 - acc: 0.6045 - val_loss: 0.6300 - val_acc: 0.6510\n",
"Epoch 3/30\n",
"100/100 [==============================] - 12s 121ms/step - loss: 0.6024 - acc: 0.6740 - val_loss: 0.5989 - val_acc: 0.6770\n",
"Epoch 4/30\n",
"100/100 [==============================] - 12s 121ms/step - loss: 0.5647 - acc: 0.7050 - val_loss: 0.5879 - val_acc: 0.6730\n",
"Epoch 5/30\n",
"100/100 [==============================] - 12s 121ms/step - loss: 0.5325 - acc: 0.7360 - val_loss: 0.5854 - val_acc: 0.6780\n",
"Epoch 6/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.5045 - acc: 0.7460 - val_loss: 0.5794 - val_acc: 0.6830\n",
"Epoch 7/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.4919 - acc: 0.7620 - val_loss: 0.5656 - val_acc: 0.6930\n",
"Epoch 8/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.4612 - acc: 0.7830 - val_loss: 0.5447 - val_acc: 0.7210\n",
"Epoch 9/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.4417 - acc: 0.7935 - val_loss: 0.5384 - val_acc: 0.7240\n",
"Epoch 10/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.4128 - acc: 0.8190 - val_loss: 0.6742 - val_acc: 0.6750\n",
"Epoch 11/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.3798 - acc: 0.8330 - val_loss: 0.6281 - val_acc: 0.7030\n",
"Epoch 12/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.3571 - acc: 0.8435 - val_loss: 0.5573 - val_acc: 0.7280\n",
"Epoch 13/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.3478 - acc: 0.8495 - val_loss: 0.5481 - val_acc: 0.7340\n",
"Epoch 14/30\n",
"100/100 [==============================] - 12s 123ms/step - loss: 0.3196 - acc: 0.8620 - val_loss: 0.5440 - val_acc: 0.7340\n",
"Epoch 15/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.2937 - acc: 0.8900 - val_loss: 0.5569 - val_acc: 0.7390\n",
"Epoch 16/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.2660 - acc: 0.8980 - val_loss: 0.5677 - val_acc: 0.7400\n",
"Epoch 17/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.2532 - acc: 0.9005 - val_loss: 0.5804 - val_acc: 0.7300\n",
"Epoch 18/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.2281 - acc: 0.9145 - val_loss: 0.5744 - val_acc: 0.7420\n",
"Epoch 19/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.2196 - acc: 0.9170 - val_loss: 0.6044 - val_acc: 0.7380\n",
"Epoch 20/30\n",
"100/100 [==============================] - 12s 125ms/step - loss: 0.1897 - acc: 0.9335 - val_loss: 0.6577 - val_acc: 0.7400\n",
"Epoch 21/30\n",
"100/100 [==============================] - 13s 126ms/step - loss: 0.1760 - acc: 0.9380 - val_loss: 0.7579 - val_acc: 0.7240\n",
"Epoch 22/30\n",
"100/100 [==============================] - 12s 123ms/step - loss: 0.1486 - acc: 0.9475 - val_loss: 0.6777 - val_acc: 0.7420\n",
"Epoch 23/30\n",
"100/100 [==============================] - 12s 123ms/step - loss: 0.1415 - acc: 0.9515 - val_loss: 0.6760 - val_acc: 0.7460\n",
"Epoch 24/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.1238 - acc: 0.9635 - val_loss: 0.7288 - val_acc: 0.7410\n",
"Epoch 25/30\n",
"100/100 [==============================] - 12s 122ms/step - loss: 0.1112 - acc: 0.9605 - val_loss: 0.7423 - val_acc: 0.7410\n",
"Epoch 26/30\n",
"100/100 [==============================] - 12s 123ms/step - loss: 0.0929 - acc: 0.9700 - val_loss: 0.8013 - val_acc: 0.7300\n",
"Epoch 27/30\n",
"100/100 [==============================] - 12s 123ms/step - loss: 0.0821 - acc: 0.9725 - val_loss: 0.8659 - val_acc: 0.7390\n",
"Epoch 28/30\n",
"100/100 [==============================] - 12s 123ms/step - loss: 0.0737 - acc: 0.9735 - val_loss: 0.9034 - val_acc: 0.7170\n",
"Epoch 29/30\n",
"100/100 [==============================] - 12s 123ms/step - loss: 0.0614 - acc: 0.9800 - val_loss: 0.8236 - val_acc: 0.7450\n",
"Epoch 30/30\n",
"100/100 [==============================] - 12s 124ms/step - loss: 0.0528 - acc: 0.9855 - val_loss: 0.8810 - val_acc: 0.7350\n"
]
}
],
"source": [
"history = model.fit_generator(\n",
" train_generator,\n",
" steps_per_epoch=100,\n",
" epochs=30,\n",
" validation_data=validation_generator,\n",
" validation_steps=50)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's plot the loss and accuracy of the model over the training and validation data during training:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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XPbdd9+UxCOJ0bGSxmjTJqTfmsxCs0alvLzaT/jJzQ1NHzUl+4TGdGZmM9y9qKFyGX2GqohklqhnaSY61Hn06OxN5o2VsR2qIpI+onaSRu2obOmhztlIyV1EmiSRk4OijnJL5/HjmULJXUTqlOz5VSDa0MF0Hj+eKZTc4xx66KHbnJB0++23c/7559f7vM6dOwOwZMkSTj755Dq3XbMDuabbb7+dirhPyTHHHMNXX30VJXSRpItaI2+uqUDSdvx4hlByjzNq1CgmT55cbdnkyZMZNare65VU2W233XjiiSca/fo1k/vzzz/Pjjvu2OjtiTRFc82vIi1DyT3OySefzHPPPcf69esBKC0tZcmSJQwbNoy1a9dy+OGHU1hYyIABA3jmmWe2eX5paSn5+flAmBpg5MiRFBQUcOqpp1ad8g9w3nnnVU0XfM011wBw5513smTJEg477DAOO+wwAPLy8li+fDkAt956K/n5+eTn51dNF1xaWsq+++7LueeeS//+/TnyyCOrvU6lZ599lgMOOIDBgwdzxBFH8OWXXwKwdu1azjrrLAYMGEBBQUHV9AUvvPAChYWFDBw4kMMPPzwp761knmyYX6VVizIYvjluDZ3EdPHF7occktzbxRc3fILAMccc408//bS7h2l3x40b5+7hjNHVq1e7u3t5ebnvueeevmXLFnd379Spk7u7L1iwwPv37+/u7rfccoufddZZ7u4+a9Ysz8nJ8enTp7v71ql2N23a5IcccojPmjXL3d1zc3O9vLy8KpbKxyUlJZ6fn+9r1671NWvWeL9+/fz999/3BQsWeE5OTtVUwKeccor/5S9/2WafVq5cWRXr/fff75dccom7u1966aV+cdybsnLlSl+2bJn37t3bP//882qx1qSTmDJXss/8TGSb0nRk+5S/zSW+aSa+ScbdueKKKygoKOCII45g8eLFVTXg2rzxxhucfvrpABQUFFBQUFC1bsqUKRQWFjJ48GDmzJlT66Rg8d566y1OOukkOnXqROfOnRkxYgRvvvkmAH379mXQoEFA3dMKl5WVcdRRRzFgwABuuukm5syZA8DLL79c7apQ3bp149133+Xggw+mb9++gKYFzjaJjGzJivlVWrG0PYkp1vLQ4k488UQuueQS3n//fdatW0dhYSEQJuIqLy9nxowZtG3blry8vFqn+Y1X2/S6CxYs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\n",
"text/plain": [
"