PyTorch安装

创建环境

conda create -n env_name python=3.x

可以先使用conda create创建一个虚拟环境,env_name为虚拟环境的名字,3.x为python的版本,例如conda create -n pytorch python=3.8

使用conda activate pytorch激活虚拟环境,conda deactivate退出环境。

CUDA版本

首先查看cuda的版本,nvidia-smi

cuda版本为10.2

官方安装

官方网站:https://pytorch.org/get-started/locally/

在官方网站点选需求可以显示安装的命令,如:

由于没有需要的CUDA版本,因此在以前的版本中寻找https://pytorch.org/get-started/previous-versions/

例如需要安装v1.12.1版本,使用Conda,Linux 或者Windows操作系统,使用如下命令:

# CUDA 10.2
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=10.2 -c pytorch

使用上述方式安装的torch版本如下:

pytorch的后缀带有py3.8_cuda10.2_cudnn7.6.5_0;torchaudio、torchvision的后缀带有py38_cu102。选择y之后就会自动安装。

或者如果使用Wheel,Linux或者Windows操作系统,使用如下命令:

# CUDA 10.2
pip install torch==1.12.1+cu102 torchvision==0.13.1+cu102 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu102

但是官方网站安装pytorch的速度较慢,因此可以选择镜像安装。把-c pytorch表示的pytorch源,更改为国内的镜像。

镜像安装

镜像地址

清华大学:https://mirrors.tuna.tsinghua.edu.cn/

阿里云:http://mirrors.aliyun.com/

镜像地址可以参考https://blog.csdn.net/djzhao627/article/details/122999240

conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=10.2 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/linux-64/

检验

import torch
print(torch.__version__)
print(torch.version.cuda)
print(torch.backends.cudnn.version())
torch.cuda.is_available()      # cuda是否可用;
torch.cuda.device_count()      # 返回gpu数量;
torch.cuda.get_device_name(0)  # 返回gpu名字,设备索引默认从0开始;
torch.cuda.current_device()    # 返回当前设备索引

PyTorch数据加载(二)

处理数据样本的代码可能会混乱且难以维护;理想情况下,希望数据集代码与模型训练代码解耦,以获得更好的可读性和模块化。PyTorch提供了两个数据基元torch.utils.data.DataLoader 和 torch.utils.data.Dataset,它们允许使用预加载的数据集以及自己的数据。Dataset存储样本及其对应的标签,DataLoader在Dataset周围包装了一个可迭代对象,以方便访问样本。

PyTorch提供了许多预加载的数据集(FashionMNIST),它们是torch.utils.data.Dataset的子类,并实现了特定于特定数据的函数。它们可以用于模型的原型和基准测试。可以在这里找到它们:图像数据集(Image Datasets),文本数据集(Text Datasets)和音频数据集(Audio Datasets)。

加载数据

这是一个如何从TorchVision加载Fashion-MNIST数据集的示例。Fashion-MNIST是Zalando的文章图像数据集,包含60,000个训练示例和10,000个测试示例。每个示例包含一个28×28灰度图像和10个类别之一的关联标签。

用以下参数加载FashionMNIST数据集:

root存储训练/测试数据的路径,
train指定训练或测试数据集,
download=True如果根目录下不可用,则从互联网上下载数据。
transform和target_transform指定了特征变换和标签变换

import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt


training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor()
)

test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor()
)

迭代和可视化数据集

可以像列表一样手动索引数据集:training_data[index]。使用matplotlib来可视化训练数据中的一些样本。

labels_map = {
    0: "T-Shirt",
    1: "Trouser",
    2: "Pullover",
    3: "Dress",
    4: "Coat",
    5: "Sandal",
    6: "Shirt",
    7: "Sneaker",
    8: "Bag",
    9: "Ankle Boot",
}
figure = plt.figure(figsize=(8, 8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):
    sample_idx = torch.randint(len(training_data), size=(1,)).item()
    img, label = training_data[sample_idx]
    figure.add_subplot(rows, cols, i)
    plt.title(labels_map[label])
    plt.axis("off")
    plt.imshow(img.squeeze(), cmap="gray")
plt.show()

为文件创建自定义数据集

一个自定义数据集类必须实现三个函数:__init____len____getitem__。FashionMNIST图像存储在目录img_dir中,它们的标签单独存储在CSV文件annotations_file中。

import os
import pandas as pd
from torchvision.io import read_image

class CustomImageDataset(Dataset):
    def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
        self.img_labels = pd.read_csv(annotations_file)
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform

    def __len__(self):
        return len(self.img_labels)

    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        image = read_image(img_path)
        label = self.img_labels.iloc[idx, 1]
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        return image, label

__init__

__init__函数在实例化Dataset对象时只运行一次。初始化包含图像、标注文件和两个transforms。标注文件如下:

tshirt1.jpg, 0
tshirt2.jpg, 0
……
ankleboot999.jpg, 9

def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
    self.img_labels = pd.read_csv(annotations_file)
    self.img_dir = img_dir
    self.transform = transform
    self.target_transform = target_transform

__len__

__len__函数返回数据集中的样本数量。

def __len__(self):
    return len(self.img_labels)

__getitem__

__getitem__函数从给定索引idx的数据集中加载并返回一个样本。根据索引,它确定图像在磁盘上的位置,使用read_image将其转换为张量,从csv数据中检索相应的标签。对它们调用transform函数(如果适用),并返回元组中的张量图像和相应的标签。

def __getitem__(self, idx):
    img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
    image = read_image(img_path)
    label = self.img_labels.iloc[idx, 1]
    if self.transform:
        image = self.transform(image)
    if self.target_transform:
        label = self.target_transform(label)
    return image, label

使用DataLoaders为训练准备数据

Dataset每次检索数据集一个样本的特征和标签。在训练模型时,通常希望以“minibatches”的方式传递样本,在每个epoch重新shuffle数据以减少模型过拟合,并使用Python的多进程处理来加速数据检索。DataLoader是一个可迭代对象,它将这种复杂性抽象为一个简单的API。

from torch.utils.data import DataLoader

train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)

遍历DataLoader

已经将该数据集加载到DataLoader中,并可以根据需要迭代该数据集。下面的每次迭代都会返回一批train_features和train_labels(分别包含batch_size=64个特征和标签)。因为指定了shuffle=True,所以在遍历完所有batches后,数据会被打乱(为了更细粒度地控制数据的加载顺序,可以看一下Samplers)。

# Display image and label.
train_features, train_labels = next(iter(train_dataloader))
print(f"Feature batch shape: {train_features.size()}")
print(f"Labels batch shape: {train_labels.size()}")
img = train_features[0].squeeze()
label = train_labels[0]
plt.imshow(img, cmap="gray")
plt.show()
print(f"Label: {label}")

输出:

Feature batch shape: torch.Size([64, 1, 28, 28])
Labels batch shape: torch.Size([64])
Label: 9

PyTorch快速入门

模型训练需要的几个基础部分包括:数据、模型、优化器、损失函数,这四个部分通过迭代不断让模型学习到输入到输出的映射关系。

数据

PyTorch有两个主要的处理数据的模块,torch.utils.data.DataLoardertorch.utils.data.DatasetDataset 存储样本及其对应的标签,DataLoader 对数据集封装了一个迭代器。

import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

PyTorch提供了特定领域的库,如TorchText、TorchVision和TorchAudio,这些库都包含数据集。此文将使用TorchVision数据集。

torchvision.datasets 模块包含许多真实世界视觉数据的数据集对象,如CIFAR和COCO。在此使用FashionMNIST数据集。每个TorchVision数据集都包含两个参数:transform和target_transform,分别用于修改样本和标签。

# Download training data from open datasets.
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)

Dataset 作为参数传递给 DataLoader。它对数据集包装了一个迭代器,并支持自动批处理(batching)、采样(sampling)、混洗(shuffling)和多进程数据加载(multiprocess data loading)。在这里,batch size定义为64,即dataloader迭代器中的每个元素将返回64个特征和标签。

batch_size = 64

# Create data loaders.
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {X.shape}")
    print(f"Shape of y: {y.shape} {y.dtype}")
    break

上述代码输出结果为:

继续阅读PyTorch快速入门

PyTorch定义神经网络

简介

深度学习使用人工神经网络(模型),它是由许多层相互连接的单元组成的计算系统。通过这些相互连接的单元传递数据,神经网络能够学习如何近似地计算将输入转换为输出所需的计算。在PyTorch中,可以使用 torch.nn 构建神经网络。

PyTorch提供了优雅设计的模块和类,包括 torch.nn,来帮助创建和训练神经网络。nn.Module 包含层,forward(input) 方法返回输出。

步骤

  1. 导入加载数据所需的所有库
  2. 定义并初始化神经网络
  3. 指定数据如何在模型中传递
  4. [可选]将数据传递给模型进行测试

导入加载数据所需的库

import torch
import torch.nn as nn
import torch.nn.functional as F

定义并初始化神经网络

该网络用于识别图像。将使用PyTorch内置的卷积过程。卷积将图像的每个元素添加到其局部邻域,由核或小矩阵加权,这有助于从输入图像中提取某些特征(如边缘检测、清晰度、模糊度等)。

定义模型的Net类有两个要求。第一个是写一个 __init__ 函数来引用 nn.Module。这个函数用于定义神经网络中所有的连接层。
使用卷积,将定义的模型以获取1个输入图像通道,输出与目标匹配,即表示数字0到9的10个标签。将遵循标准MNIST算法。

class Net(nn.Module):
    def __init__(self):
      super(Net, self).__init__()

      self.conv1 = nn.Conv2d(1, 32, 3, 1)
      self.conv2 = nn.Conv2d(32, 64, 3, 1)

      self.dropout1 = nn.Dropout2d(0.25)
      self.dropout2 = nn.Dropout2d(0.5)

      self.fc1 = nn.Linear(9216, 128)
      self.fc2 = nn.Linear(128, 10)

my_nn = Net()
print(my_nn)

已经定义了神经网络,然后必须定义数据如何通过网络。

指定数据如何通过模型

当使用PyTorch构建模型时,需要定义 forward 函数,它将数据传递到计算图,表示前馈算法。可以在前向函数中使用任何张量运算。

class Net(nn.Module):
    def __init__(self):
      super(Net, self).__init__()
      self.conv1 = nn.Conv2d(1, 32, 3, 1)
      self.conv2 = nn.Conv2d(32, 64, 3, 1)
      self.dropout1 = nn.Dropout2d(0.25)
      self.dropout2 = nn.Dropout2d(0.5)
      self.fc1 = nn.Linear(9216, 128)
      self.fc2 = nn.Linear(128, 10)


    def forward(self, x):
      x = self.conv1(x)
      x = F.relu(x)
      x = self.conv2(x)
      x = F.relu(x)
      x = F.max_pool2d(x, 2)
      x = self.dropout1(x)
      x = torch.flatten(x, 1)  # Flatten x with start_dim=1
      x = self.fc1(x)  # Pass data through fc1
      x = F.relu(x)
      x = self.dropout2(x)
      x = self.fc2(x)
      output = F.log_softmax(x, dim=1)  # Apply softmax to x
      return output

[可选]将数据传递给模型进行测试

为了确保收到所需的输出,通过传递一些随机数据来测试模型。

# Equates to one random 28x28 image
random_data = torch.rand((1, 1, 28, 28))

my_nn = Net()
result = my_nn(random_data)
print (result)

PyTorch数据加载(一)

简介

PyTorch具有广泛的神经网络构建模块,具有简单、直观和稳定的API。PyTorch包含为模型准备和加载公共数据集的包。

PyTorch数据加载实用工具的核心是torch.utils.data.DataLoader类。它表示数据集上的Python迭代器。PyTorch在torch.utils.data.Dataset类中提供了内置的高质量数据集。它们允许使用预加载的数据集以及自己的数据。Dataset存储样本及其对应的标签,DataLoader在Dataset周围包装了一个可迭代对象,以方便访问样本。这些数据集目前包含:

使用torchaudio.datasets中的Yesno数据集演示如何高效地将数据从PyTorch Dataset 加载到PyTorch DataLoader 中。

安装

需要安装 torchaudio 以访问数据集,pip install torchaudio

要在谷歌Colab中运行,取消注释,!pip install torchaudio

步骤

  1. 导入加载数据所需的所有库
  2. 访问数据集中的数据
  3. 加载数据
  4. 遍历数据
  5. [可选]可视化数据

导入加载数据所需的所有库

在这个样例中,使用 torchtorchaudio。根据使用的内置数据集,还可以安装和导入torchvisiontorchtext

import torch
import torchaudio

访问数据集中的数据

torchaudio中的Yesno数据集有60段记录,记录的是一个人用希伯来语说“yes”或“no”;每段录音有8个单词长。torchaudio.datasets.YESNO为YesNo创建数据集

yesno_data = torchaudio.datasets.YESNO(
     root='./',
     url='http://www.openslr.org/resources/1/waves_yesno.tar.gz',
     folder_in_archive='waves_yesno',
     download=True)

数据集中的每一项都是元组:(waveform, sample_rate, labels)。对Yesno数据集必须设置root参数,用于存储训练和测试数据集。其他参数是可选的,显示了它们的默认值。

加载数据

现在可以访问数据集了,将它传递给torch.utils.data.DataLoader。DataLoader将数据集和采样器结合起来,返回一个遍历数据集的迭代器。

data_loader = torch.utils.data.DataLoader(yesno_data,
                                          batch_size=1,
                                          shuffle=True)

遍历数据

数据现在可以使用data_loader进行迭代了。当开始训练模型时,这将是必要的!现在data_loader对象中的每个数据条目都被转换为一个张量,其中包含表示waveform、sample rate和labels的张量。

for data in data_loader:
  print("Data: ", data)
  print("Waveform: {}\nSample rate: {}\nLabels: {}".format(data[0], data[1], data[2]))
  break

可视化数据

可以选择将数据可视化,以进一步理解DataLoader的输出

import matplotlib.pyplot as plt

print(data[0][0].numpy())

plt.figure()
plt.plot(waveform.t().numpy())

论文笔记:Calculating Question Similarity is Enough: A New Method for KBQA Tasks

摘要

知识库问答(KBQA)的目的是在外部知识库的帮助下回答自然语言问题。其核心思想是找到问题背后的内部知识与知识库中已知三元组之间的联系。传统的KBQA任务piplines包含实体识别、实体链接、答案选择等步骤。在这种pipline方法中,任何过程中的错误都会不可避免地传播到最终的预测。为了解决这一问题,论文提出了一种基于预训练语言模型的语料库生成-检索方法(Corpus Generation – Retrieve Method,CGRM)。主要的创新之处在于新方法的设计。其中,知识增强T5 (kT5)模型旨在基于知识图谱三元组生成自然语言QA对,并通过检索合成数据集直接求解QA。该方法可以从PLM中提取更多的实体信息,提高精度,简化过程。我们在NLPCC-ICCPOL 2016 KBQA数据集上测试了我们的方法,结果表明该方法提高了KBQA的性能,并且与最先进的方法相比具有竞争力。

背景和挑战

问答系统是自然语言处理领域长期以来的研究热点。一个方向是将已有的知识库用于自然语言问题,称为知识库问答(Knowledge Base Question Answering, KBQA)。目前KBQA的主流方法是将当前问句的实体链接到KBQA实体中,利用句子中出现的关系归纳到知识图谱中得到最终答案。目前,KBQA任务主要通过一组分步处理的pipline来解决,包括实体识别、关系抽取、实体链接、答案选择,如图1所示。在应用上述pipline方法时,中途发生的任何错误都会影响到后续所有的pipline链接,从而在很大程度上降低整个KBQA系统的性能。

图1
继续阅读论文笔记:Calculating Question Similarity is Enough: A New Method for KBQA Tasks

知识图谱文本生成调研

通过特定任务和开放世界知识增强文本生成

论文:TEGTOK: Augmenting Text Generation via Task-specific and Open-world Knowledge

代码:https://github.com/lxchtan/TEGTOK

摘要

生成自然且信息丰富的文本一直是NLP中的一个长期问题。许多工作致力于将预训练语言模型(PLMs)与各种开放世界知识(如知识图谱或wiki页面)结合起来。然而,他们访问和操作特定任务知识的能力仍然局限于下游任务,因为这种类型的知识通常在PLMs中没有很好地覆盖,并且很难获得。为解决该问题,论文提出在统一框架中通过特定任务和开放世界知识增强文本生成。该模型通过密集检索从两类知识源中选择知识条目,并基于PLMs分别注入到输入编码和输出解码阶段。在这两种知识的帮助下,模型可以学习生成什么以及如何生成。在对话生成问题生成两个文本生成任务以及两个数据集上的实验表明,该方法取得了比各种基线模型更好的性能。

挑战

  • 尽管目前的生成模型能够使用编码器-解码器架构或语言模型生成自然和流畅的目标序列,但它们通常只提供有限的知识来生成所需的输出。因此,在许多现实世界的场景中,文本生成的性能仍然远远不能令人满意。
  • 尽管开放世界知识(如结构化知识库,ConceptNet或非结构化文档,如来自维基百科的文档)在大多数情况下可以改善生成过程,但其效果仍局限于涉及较少实体或抽象语义的情况。另一方面,人类生成文本的过程往往基于一种以上的知识感知。除了世界知识,特定于任务的知识也作为重要的信息源,通常在PLMs中没有很好地覆盖,并且很难通过微调获得。

解决方法

基于上述问题,本文提出了augmentation TExt Generation via Task-specific and Open-world Knowledge (TEGTOK)。

  1. 假设世界知识是非结构化的维基百科文档,提供了输入序列中提到的实体的补充信息或背景知识。特定于任务的知识是一个预先构建的索引,与领域相关,并作为指导文本生成的示范性信息源。它可以根据不同的任务或领域进行灵活调整,例如对话生成中的上下文-反应对或问题生成中的篇章-问题对。
  2. 受开放域问答任务中密集检索方法成功的启发,使用预训练编码器将输入文本和知识条目转换为密集表示向量,并采用快速最大内积搜索(MIPS)完成检索,以保证知识选择的有效性和效率。
  3. 最后,将这两类知识分别注入到源文本编码和目标文本解码阶段。通过这种方式,该模型可以在两类知识的帮助下,在统一的框架中学习如何生成以及生成什么。
继续阅读知识图谱文本生成调研

faiss的安装及简单使用

pip安装

直接使用pip安装pip install faiss

在python环境中import faiss会报错

使用如下的命令安装可以成功

pip –default-time=1000 install -i https://pypi.tuna.tsinghua.edu.cn/simple faiss-cpu

conda安装

只安装cpu版本

$ conda install -c pytorch faiss-cpu

安装gpu+cpu版本

$ conda install -c pytorch faiss-gpu

指定cuda版本

$ conda install -c pytorch faiss-gpu cudatoolkit=10.2 # for CUDA 10.2

faiss的简单使用

构建数据集

使用xb矩阵建立索引,xb的每一行都是被检索的对象,维度是(nb,d) 。xq矩阵,是用来检索的向量集合的矩阵,对其中的每个向量,需要找到它的前K个相似向量,维度是(nq,d)。当只检索一个向量的时候,nq=1

import numpy as np
d = 64                           # dimension
nb = 100000                      # database size
nq = 10000                       # nb of queries
np.random.seed(1234)             # make reproducible
xb = np.random.random((nb, d)).astype('float32')
xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.

建立索引并加入向量

Faiss中有多种类型的索引,使用最简单的索引类型:IndexFlatL2,这是暴力检索L2距离,也就是最常规的计算距离的方式。对于大部分索引类型而言,在建立它们时都包含训练阶段,但是对于IndexFlatL2这个索引,可以跳过这一步。 当索引被建立和训练之后,可以调用add和search这两种方法。 还可以使用两种查找索引状态的方法 is_trianed,来表明索引是否已经被训练过。ntotal来得到当前索引中向量的个数。对于一些类型的索引来说,还可以存储每个向量对应的整数ID(IndexFlatL2不行),如果没有提供ID,那么索引就是的第一个向量索引为0,第二个向量索引为1,以此类推。

import faiss                   # make faiss available
index = faiss.IndexFlatL2(d)   # build the index
print(index.is_trained)
index.add(xb)                  # add vectors to the index
print(index.ntotal)
  • 第一个print的结果:True,已经经过训练,IndexFlatL2不需要训练,因此为True
  • 第二个print的结果:10000,xb得维度是10000

检索

对于每个检索向量,都能从索引中得到前K近个向量。

k = 4                          # we want to see 4 nearest neighbors
D, I = index.search(xb[:5], k) # sanity check
print(I)
print(D)
D, I = index.search(xq, k)     # actual search
print(I[:5])                   # neighbors of the 5 first queries

参考

faiss包安装_Alicesla的博客-CSDN博客_faiss包安装

Faiss库使用方法(一) – 知乎 (zhihu.com)

安装mxnet报错OSError: libcudnn.so.8

安装流程

pip install mxnet-cu102

安装好了之后在python中import mxnet,报了OSError: libcudnn.so.8: cannot open shared object file: No such file or directory错误

解决方案

方案1

改变mxnet的版本,卸载之后重新尝试了mxnet-cu100和mxnet-cu110,依然报相同的错误,未解决

方案2

网上看了很多解决方案,因为没有sudo权限所以没有尝试

官网上看到docker的安装方法所以尝试

首先要安装NVIDIA的docker驱动,然后拉取镜像docker pull mxnet/python:gpu,mxnet/python 的docker hub里只有1.9版本的镜像,但在拉取镜像的过程中报错

这样可以选择拉取别人上传的镜像也可以拉取一个linux镜像重新搭建需要的cuda和cuDNN版本

拉取镜像构建容器参考Docker容器构建

方案3

最后的解决方法有点简单,兜兜转转一圈回来下载一个低版本的安装便成功了

pip install mxnet-cu102==1.6.0.post0 -i https://pypi.tuna.tsinghua.edu.cn/simple/

直接pip install mxnet-cu102安装的版本是1.9.1会报错,1.6.0版本没有报错

其他方案

在虚拟环境下装个10.1 cudatookit

先执行conda install cudatoolkit=10.1 -c pytorch
再pip install mxnet-cu101==1.5.1 -i https://pypi.tuna.tsinghua.edu.cn/simple/

上述方案也可以将mxnet安装成功

Docker构建容器

Docker概述

docker docs

docker hub

docker架构

Docker使用客户端-服务器架构。Docker客户端(client )与Docker守护进程(daemon)通信,后者负责构建、运行和分发Docker容器的繁重工作。Docker客户端和Docker守护进程可以在同一个系统上运行,也可以将Docker客户端连接到远程的Docker守护进程。Docker客户端和守护进程使用REST API通过UNIX套接字(sockets )或网络接口通信。另一个Docker客户端是Docker Compose,它允许使用由一组容器组成的应用程序。

图片来自docker官方网站https://docs.docker.com/get-started/overview/

镜像

镜像是一个只读的模板,包含创建Docker容器的说明。通常,一个镜像基于另一个镜像,并有一些额外的定制。例如,可以构建一个基于ubuntu镜像的镜像,安装Apache web服务器和应用程序,以及运行应用程序所需的配置细节。可以创建自己的镜像,也可以只使用其他人创建并在注册表中发布的镜像。要构建自己的镜像,需要创建一个Dockerfile,使用简单的语法定义创建和运行镜像所需的步骤。Dockerfile中的每一条指令都会在镜像中创建一个层。当更改Dockerfile并重建镜像时,只有那些更改的层会被重建。与其他虚拟化技术相比,这是使镜像轻量级、小巧和快速的部分原因。

容器

容器是镜像的可运行实例。

  • 可以使用Docker API或CLI创建、启动、停止、移动或删除容器。
  • 可以将容器连接到一个或多个网络,为其附加存储空间,甚至根据其当前状态创建新镜像。默认情况下,一个容器与其他容器及其宿主机是相对隔离的。
  • 可以控制容器的网络、存储或其他底层子系统与其他容器或主机的隔离程度。
  • 容器由它的镜像以及在创建或启动它时提供给它的配置选项定义。当容器被移除时,任何未存储在持久存储中的对其状态的更改都会消失。

容器是一个sandboxed process,与主机上的所有其他进程隔离。这种隔离利用了kernel namespaces和cgroups。可以在本地机器、虚拟机上运行或部署到云端;具有可移植性(可以在任何操作系统上运行);与其他容器隔离,并运行自己的软件、二进制文件和配置。

运行一个ubuntu容器,以交互方式连接到本地命令行会话,然后运行 /bin/bash

docker run -i -t ubuntu /bin/bash

当您运行此命令时,将发生以下情况(假设您使用默认注册表配置):

  1. 如果您没有本地的ubuntu镜像,Docker将从配置的注册表中拉取它,就像手动运行Docker pull ubuntu一样。
  2. Docker会创建一个新容器,就像手动运行Docker container create命令一样。
  3. Docker为容器分配了一个读写文件系统,作为它的最后一层。这允许一个正在运行的容器在其本地文件系统中创建或修改文件和目录。
  4. 由于没有指定任何网络选项,Docker会创建一个网络接口将容器连接到默认网络。这包括为容器分配IP地址。默认情况下,容器可以使用主机的网络连接连接到外部网络。
  5. Docker启动容器并执行/bin/bash.因为容器以交互方式运行,并且连接到终端(因为有-i和-t标志),所以可以使用键盘提供输入,同时将输出记录到终端。
  6. 当你输入exit来终止/bin/bash命令时,容器会停止,但不会被移除。您可以重新启动它或删除它。

容器镜像

当运行容器时,它使用一个隔离的文件系统。这个自定义文件系统由容器镜像提供。镜像包含容器的文件系统,它必须包含运行应用程序所需的一切——所有依赖项、配置、脚本、二进制文件等。镜像还包含容器的其他配置,如环境变量、要运行的默认命令和其他元数据。

Docker实践

第一步

在工程项目文件夹中写好Dockerfile,如下:

FROM 安装好anaconda3的镜像

ADD ./ /opt/test/

WORKDIR /opt/test/

RUN apt update -y && apt install -y libopenblas-dev

RUN /root/anaconda3/envs/cpu/bin/pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

RUN chmod +x ./start.sh

CMD [“/bin/sh”,”-c”, “./start.sh”]

拉取一个具有相关配置和环境的镜像;

然后将当前文件夹中的文件添加到容器中/opt/test的目录下;

工作目录为/opt/text;

然后更新安装包并安装libopenblas-dev;

再安装项目依赖的第三方库;

运行当前目录下的start.sh文件

第二步

执行docker build -t image_name ./ –network=host

第三步

镜像构建好了之后使用docker run -itd -p 12345:12345 –name contrainer_name image_name构建容器

因为我的项目是一个web服务,因此设置了端口的对应关系,宿主机的端口12345,对应容器内的端口为12345

简单docker命令

列出本地镜像使用docker image命令

查看容器信息使用命令docker ps -a,得到容器ID(CONTAINER ID)。

使用命令docker exec -it CONTAINER ID /bin/bash进入容器

使用ctrl+D或者exit退出容器

使用docker start CONTAINER ID可以启动

复制本地文件到docker容器中docker cp

docker cp 源文件夹/文件 容器ID:目标文件夹

宿主机和docker中的文件关联 ,使用-v

例如:使用镜像bitnami/mxnet

docker run -itd –name mxnet1 -v /home/project/:/opt/test/ bitnami/mxnet

此命令将宿主机的文件和容器中的文件指向同一个地址,修改其中一个可以同步到另一个,比如在宿主机中添加一个文件,文件会同步到docker容器中