Kubernetes权威指南——深入掌握Pod(Pod的扩缩容)

本文深入讲解Kubernetes中Pod的扩缩容机制,重点涵盖手动扩缩容(kubectl scale)与自动扩缩容(HPA)原理及实践。详细解析HorizontalPodAutoscaler工作流程、支持的三类指标(资源使用率、Pod自定义指标、Object/外部指标)、扩缩容核心算法(含容忍度与异常Pod处理)、autoscaling/v1与v2beta2配置差异,并基于Prometheus Adapter完成自定义指标HPA的端到端部署与验证。

12、Pod的扩缩容

在实际生产系统中,我们经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。此时可以利用Deployment/RC的Scale机制来完成这些工作。

Kubernetes对Pod的扩缩容操作提供了手动和自动两种模式,手动模式通过执行kubectl scale命令或通过RESTful API对一个Deployment/RC进行Pod副本数量的设置,即可一键完成。自动模式则需要用户根据某个性能指标或者自定义业务指标,并指定Pod副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整。

12.1、手动扩缩容机制

以Deployment nginx为例:

apiVersion: apps/v1
kind: Deployment             # 资源类型:Kubernetes Deployment(工作负载控制器)
metadata:
  name: nginx-deployment     # Deployment 的名称
spec:
  replicas: 3                # 期望运行的 Pod 副本数量(这里是 3 个)
  selector:                  # 标签选择器:Deployment 通过此规则来关联和管理哪些 Pod
    matchLabels:
      app: nginx             # 必须与下方 template 中的标签保持一致
  template:
    metadata:
      labels:
        app: nginx           # 为该 Deployment 创建的 Pod 打上标签
    spec:
      containers:
      - name: nginx          # 容器名称
        image: nginx:1.7.9   # 使用的 Nginx 镜像及指定版本
        ports:
        - containerPort: 80  # 容器监听的端口

已运行的Pod副本数量为3个:

$ kubectl get pods
NAME                                      READY     STATUS    RESTARTS   AGE
nginx-deployment-3973253433-scz37   1/1       Running   0           5s
nginx-deployment-3973253433-x8fsq   1/1       Running   0           5s
nginx-deployment-3973253433-x9z8z   1/1       Running   0           5s

通过kubectl scale命令可以将Pod副本数量从初始的3个更新为5个:

$ kubectl scale deployment nginx-deployment --replicas 5
deployment "nginx-deployment" scaled
$ kubectl get pods
NAME                                      READY     STATUS    RESTARTS   AGE
nginx-deployment-3973253433-3gt27   1/1       Running   0           4s
nginx-deployment-3973253433-7jls2   1/1       Running   0           4s
nginx-deployment-3973253433-scz37   1/1       Running   0           4m
nginx-deployment-3973253433-x8fsq   1/1       Running   0           4m
nginx-deployment-3973253433-x9z8z   1/1       Running   0           4m

将–replicas设置为比当前Pod副本数量更小的数字,系统将会“杀掉”一些运行中的Pod,以实现应用集群缩容:

$ kubectl scale deployment nginx-deployment --replicas=1
deployment "nginx-deployment" scaled

$ kubectl get pods
NAME                                      READY     STATUS    RESTARTS   AGE
nginx-deployment-3973253433-x9z8z   1/1       Running   0          6m

12.2、自动扩缩容机制

Kubernetes从1.1版本开始,新增了名为Horizontal PodAutoscaler(HPA)的控制器,用于实现基于CPU使用率进行自动Pod扩缩容的功能。HPA控制器基于Master的kube-controller-manager服务启动参数–horizontal-pod-autoscaler-sync-period定义的探测周期(默认值为15s)​,周期性地监测目标Pod的资源性能指标,并与 HPA资源对象中的扩缩容条件进行对比,在满足条件时对Pod副本数量进行调整。

Kubernetes在早期版本中,只能基于Pod的CPU使用率进行自动扩缩容操作,关于CPU使用率的数据来源于Heapster组件。Kubernetes从1.6版本开始,引入了基于应用自定义性能指标的HPA机制,并在1.9版本之后逐步成熟。本节对Kubernetes的HPA的原理和实践进行详细说明。

12.2.1、HPA的工作原理

Kubernetes中的某个Metrics Server(Heapster或自定义Metrics Server)持续采集所有Pod副本的指标数据。HPA控制器通过Metrics Server的API(Heapster的API或聚合API)获取这些数据,基于用户定义的扩缩容规则进行计算,得到目标Pod副本数量。当目标Pod副本数量与当前副本数量不同时,HPA控制器就向Pod的副本控制器(Deployment、RC或ReplicaSet)发起scale操作,调整Pod的副本数量,完成扩缩容操作。下图描述了HPA体系中的关键组件和工作流程。

在这里插入图片描述
接下来首先对HPA能够管理的指标类型、扩缩容算法、HPA对象的配置进行详细说明,然后通过一个完整的示例对如何搭建和使用基于自定义指标的HPA体系进行说明。

12.2.2、指标的类型

Master的kube-controller-manager服务持续监测目标Pod的某种性能指标,以计算是否需要调整副本数量。目前Kubernetes支持的指标类型如下。

  • Pod资源使用率:Pod级别的性能指标,通常是一个比率值,例如CPU使用率。
  • Pod自定义指标:Pod级别的性能指标,通常是一个数值,例如接收的请求数量。
  • Object自定义指标或外部自定义指标:通常是一个数值,需要容器应用以某种方式提供,例如通过HTTP URL“/metrics”提供,或者使用外部服务提供的指标采集URL。

Kubernetes从1.11版本开始,弃用基于Heapster组件完成Pod的CPU使用率采集的机制,全面转向基于MetricsServer完成数据采集。Metrics Server将采集到的Pod性 能指标数据通过聚合API(Aggregated API)如metrics.k8s.io 、 custom.metrics.k8s.io和external.metrics.k8s.io提供给HPA控制器进行查询。关于聚合API和API聚合器(API Aggregator)的概念详见9.4节的说明。

12.2.3、扩缩容算法详解

Autoscaler控制器从聚合API获取到Pod性能指标数据之后,基于下面的算法计算出目标Pod副本数量,与当前运行的Pod副本数量进行对比,决定是否需要进行扩缩容操作:

desiredReplicas = ceil[currentReplicas * ( currentMetricValue /
desiredMetricValue )]

即当前副本数×(当前指标值/期望的指标值)​,将结果向上取整。

以CPU请求数量为例,如果用户设置的期望指标值为100m,当前实际使用的指标值为200m,则计算得到期望的Pod副本数量应为两个(200/100=2)​。如果设置的期望指标值为50m,计算结果为0.5,则向上取整值为1,得到目标Pod副本数量应为1个。

当计算结果与1非常接近时,可以设置一个容忍度让系统不做扩缩容操作。容忍度通过kube-controller-manager服务的启动参数–horizontal-pod-autoscaler-tolerance进行设置,默认值为0.1(即10%)​,表示基于上述算法得到的结果在[-10%-+10%]区间内,即[0.9-1.1]​,控制器都不会进行扩缩容操作。

也可以将期望指标值(desiredMetricValue)设置为指标的平均值类型,例如targetAverageValue或targetAverageUtilization,此时当前指标值(currentMetricValue)的算法为所有Pod副本当前指标值的总和除以Pod副本数量得到的平均值。

此外,存在几种Pod异常的情况,如下所述。

  • Pod正在被删除(设置了删除时间戳)​:将不会计入目标Pod副本数量。
  • Pod的当前指标值无法获得:本次探测不会将这个Pod纳入目标Pod副本数量,后续的探测会被重新纳入计算范围。
  • 如果指标类型是CPU使用率,则对于正在启动但是还未达到Ready状态的Pod,也暂时不会纳入目标副本数量范围。可以通过kube-controller-manager服务的启动参数–horizontal-pod-autoscaler-initial-readiness-delay设置首次探测Pod是否Ready的延时时间,默认值为30s。另一个启动参数–horizontal-pod-autoscaler-cpu-initialization-period设置首次采集Pod的CPU使用率的延时时间。

在计算“当前指标值/期望的指标值”​(currentMetricValue / desiredMetricValue)时将不会包括上述这些异常Pod。

当存在缺失指标的Pod时,系统将更保守地重新计算平均值。系统会假设这些Pod在需要缩容(Scale Down)时消耗了期望指标值的100%,在需要扩容(Scale Up)时消耗了期望指标值的0%,这样可以抑制潜在的扩缩容操作。

此外,如果存在未达到Ready状态的Pod,并且系统原本会在不考虑缺失指标或NotReady的Pod情况下进行扩展,则系统仍然会保守地假设这些Pod消耗期望指标值的0%,从而进一步抑制扩容操作。

如果在HorizontalPodAutoscaler中设置了多个指标,系统就会对每个指标都执行上面的算法,在全部结果中以期望副本数的最大值为最终结果。如果这些指标中的任意一个都无法转换为期望的副本数(例如无法获取指标的值)​,系统就会跳过扩缩容操作。

最后,在HPA控制器执行扩缩容操作之前,系统会记录扩缩容建议信息(Scale Recommendation)​。控制器会在操作时间窗口(时间范围可以配置)中考虑所有的建议信息,并从中选择得分最高的建议。这个值可通过kube-controller-manager服务的启动参数–horizontal-pod-autoscaler-downscale-stabilization-window进行配置,默认值为5min。这个配置可以让系统更为平滑地进行缩容操作,从而消除短时间内指标值快速波动产生的影响。

12.2.4、HorizontalPodAutoscaler配置详解

Kubernetes将HorizontalPodAutoscaler资源对象提供给用户来定义扩缩容的规则。

HorizontalPodAutoscaler资源对象处于Kubernetes的API组“autoscaling”中,目前包括v1和v2两个版本。其中autoscaling/v1仅支持基于CPU使用率的自动扩缩容,autoscaling/v2则用于支持基于任意指标的自动扩缩容配置,包括基于资源使用率、Pod指标、其他指标等类型的指标数据,当前版本为autoscaling/v2beta2。

下面对HorizontalPodAutoscaler的配置和用法进行说明。

  • (1)基于autoscaling/v1版本的HorizontalPodAutoscaler配置,仅可以设置CPU使用率:

    apiVersion: autoscaling/v1
    kind: HorizontalPodAutoscaler     # 资源类型:水平 Pod 自动扩缩容控制器 (HPA)
    metadata:
      name: php-apache                # HPA 的名称
    spec:
      scaleTargetRef:
        apiVersion: apps/v1           # 目标控制器的 API 版本
        kind: Deployment              # 目标控制器类型(这里是 Deployment)
        name: php-apache              # 目标 Deployment 的名称
      minReplicas: 1                  # 最小 Pod 副本数:当负载很低时,缩容到的最少副本数
      maxReplicas: 10                 # 最大 Pod 副本数:当负载很高时,扩容到的最多副本数
      targetCPUUtilizationPercentage: 50 # 目标 CPU 平均利用率:当所有 Pod 的平均 CPU 利用率超过 50% 时,HPA 会触发扩容
    

    主要参数如下。

    • scaleTargetRef :目标作用对象,可以是Deployment 、 ReplicationController或ReplicaSet。
    • targetCPUUtilizationPercentage:期望每个Pod的CPU使用率都为50%,该使用率基于Pod设置的CPU Request值进行计算,例如该值为200m,那么系统将维持Pod的实际CPU使用值为100m。
    • minReplicas和maxReplicas:Pod副本数量的最小值和最大值,系统将在这个范围内进行自动扩缩容操作,并维持每个Pod的CPU使用率为50%。

    为了使用autoscaling/v1版本的HorizontalPodAutoscaler,需要预先安装Heapster组件或Metrics Server,用于采集Pod的CPU使用率。Heapster从Kubernetes 1.11版本开始进入弃用阶段,本节不再对Heapster进行详细说明。关于Metrics Server的说明请参考9.4节的介绍,本节主要对基于自定义指标进行自动扩缩容的设置进行说明。

  • (2)基于autoscaling/v2beta2的HorizontalPodAutoscaler配置:

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler     # 资源类型:水平 Pod 自动扩缩容控制器 (HPA)
    metadata:
      name: php-apache                # HPA 的名称
    spec:
      scaleTargetRef:
        apiVersion: apps/v1           # 目标控制器的 API 版本
        kind: Deployment              # 目标控制器类型(这里是 Deployment)
        name: php-apache              # 目标 Deployment 的名称
      minReplicas: 1                  # 最小 Pod 副本数:当负载很低时,缩容到的最少副本数
      maxReplicas: 10                 # 最大 Pod 副本数:当负载很高时,扩容到的最多副本数
      metrics:                        # 扩缩容的监控指标配置
      - type: Resource                # 指标类型:基于资源(如 CPU、内存)
        resource:
          name: cpu                   # 监控的目标资源类型为 CPU
          target:
            type: Utilization         # 目标指标类型为资源利用率
            averageUtilization: 50    # 目标 CPU 平均利用率:当所有 Pod 的平均 CPU 利用率超过 50% 时触发扩容
    

    主要参数如下。

    • scaleTargetRef :目标作用对象,可以是Deployment 、 ReplicationController或ReplicaSet。
    • minReplicas和maxReplicas:Pod副本数量的最小值和最大值,系统将在这个范围内进行自动扩缩容操作,并维持每个Pod的CPU使用率为50%。
    • metrics:目标指标值。在metrics中通过参数type定义指标的类型;通过参数target定义相应的指标目标值,系统将在指标数据达到目标值时(考虑容忍度的区间,见前面算法部分的说明)触发扩缩容操作。

可以将metrics中的type(指标类型)设置为以下三种,可以设置一个或多个组合,如下所述。

  • Resource:基于资源的指标值,可以设置的资源为CPU和内存。
  • Pods:基于Pod的指标,系统将对全部Pod副本的指标值进行平均值计算。
  • Object:基于某种资源对象(如Ingress)的指标或应用系统的任意自定义指标。

Resource类型的指标可以设置CPU和内存。对于CPU使用率,在target参数中设置averageUtilization定义目标平均CPU使用率。对于内存资源,在target参数中设置AverageValue定义目标平均内存使用值。指标数据可以通过API“metrics.k8s.io”进行查询,要求预先启动Metrics Server服务。

Pods类型和Object类型都属于自定义指标类型,指标的数据通常需要搭建自定义Metrics Server和监控工具进行采集和处理。指标数据可以通过API“custom.metrics.k8s.io”进行查询,要求预先启动自定义Metrics Server服务。

类型为Pods的指标数据来源于Pod对象本身,其target指标类型只能使用AverageValue,示例如下:

metrics:
- type: Pods                  # 指标类型:Pods 指标,针对所有 Pod 的某个自定义指标计算平均值
  pods:
    metric:
      name: packets-per-second # 自定义指标的名称(通常由 Prometheus Adapter 等指标适配器收集并提供给 K8s API)
    target:
      type: AverageValue      # 目标类型:平均值类型(将所有 Pod 的该指标总和除以当前 Pod 副本数)
      averageValue: 1k        # 目标阈值:当每个 Pod 的平均每秒数据包数(packets-per-second)达到 1k(即 1000)时,HPA 将触发扩容

其中,设置Pod的指标名为packets-per-second,在目标指标平均值为1000时触发扩缩容操作。

类型为Object的指标数据来源于其他资源对象或任意自定义指标,其target指标类型可以使用Value或AverageValue(根据Pod副本数计算平均值)进行设置。下面对几种常见的自定义指标给出示例和说明。

例1,设置指标的名称为requests-per-second,其值来源于Ingress“main-route”​,将目标值(value)设置为2000,即在Ingress的每秒请求数量达到2000个时触发扩缩容操作:

metrics:
- type: Object                    # 指标类型:Object 指标,用于监控非 Pod 的其他 Kubernetes 资源(如 Ingress、Service 等)
  object:
    metric:
      name: requests-per-second   # 自定义指标名称(例如通过 Prometheus 收集的每秒请求数)
    describedObject:
      apiVersion: networking.k8s.io/v1  # 目标资源的 API 版本(旧版本常写为 extensions/v1beta1)
      kind: Ingress               # 目标资源类型(这里是 Ingress)
      name: main-route            # 目标 Ingress 的名称
    target:
      type: Value                 # 目标类型:绝对值类型(针对整个对象实例的总体指标值)
      value: 2k                   # 目标阈值:当该 Ingress 的总每秒请求数达到 2k(即 2000)时,HPA 将触发扩容

例2,设置指标的名称为http_requests,并且该资源对象具有标签“verb=GET”​,在指标平均值达到500时触发扩缩容操作:

metrics:
- type: Object                    # 指标类型:Object 指标,用于监控非 Pod 资源的自定义指标
  object:
    metric:
      name: http_requests         # 监控的指标名称
      selector:
        matchLabels:
          verb: GET               # 标签选择器:使用标准的 matchLabels 来过滤特定的请求(例如只统计 GET 请求)
    describedObject:
      apiVersion: networking.k8s.io/v1
      kind: Service               # 目标资源类型(这里以 Service 为例)
      name: my-service            # 目标资源的名称
    target:
      type: AverageValue          # 目标类型:平均值类型
      averageValue: 500           # 目标阈值:当该对象的指定请求平均值达到 500 时触发扩容

还可以在同一个HorizontalPodAutoscaler资源对象中定义多个类型的指标,系统将针对每种类型的指标都计算Pod副本的目标数量,以最大值为准进行扩缩容操作。例如:

apiVersion: autoscaling/v2          # 推荐使用现代的 autoscaling/v2 API 版本
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:                        # 组合了多种类型的自动扩缩容指标
  - type: Resource                # 1. 资源指标:监控 CPU 利用率
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50    # 当平均 CPU 利用率超过 50% 时触发扩容
  - type: Pods                    # 2. Pods 指标:针对所有 Pod 的自定义指标
    pods:
      metric:
        name: packets-per-second
      target:
        type: AverageValue        # v2 版本标准语法:使用 target 嵌套块定义类型和阈值
        averageValue: 1k
  - type: Object                  # 3. Object 指标:监控非 Pod 资源(如 Ingress)的指标
    object:
      metric:
        name: requests-per-second
      describedObject:
        apiVersion: networking.k8s.io/v1  # 推荐将旧的 extensions/v1beta1 更新为 networking.k8s.io/v1
        kind: Ingress
        name: main-route
      target:
        type: Value               # v2 版本标准语法:使用 target 嵌套块定义类型和阈值
        value: 10k

从1.10版本开始,Kubernetes引入了对外部系统指标的支持。例如,用户使用了公有云服务商提供的消息服务或外部负载均衡器,希望基于这些外部服务的性能指标(如消息服务的队列长度、负载均衡器的QPS)对自己部署在Kubernetes中的服务进行自动扩缩容操作。这时,就可以在metrics参数部分设置type为External来设置自定义指标,然后就可以通过API“external.metrics.k8s.io”查询指标数据了。当然,这同样要求自定义Metrics Server服务已正常工作。

例3,设置指标的名称为queue_messages_ready,具有queue=worker_tasks标签在目标指标平均值为30时触发自动扩缩容操作:

metrics:
- type: External                    # 指标类型:External 指标,用于监控 Kubernetes 集群外部的系统指标(如云服务或外部消息队列)
  external:
    metric:
      name: queue_messages_ready    # 外部监控系统中的指标名称(例如 RabbitMQ 队列中准备就绪的消息数)
      selector:
        matchLabels:
          queue: worker_tasks       # 标签选择器:使用标准的 matchLabels 来过滤特定的队列实例
    target:
      type: AverageValue            # 目标类型:平均值类型
      averageValue: 30              # 目标阈值:当外部队列中每个实例的平均就绪消息数达到 30 时,HPA 将触发扩容

在使用外部服务的指标时,要安装、部署能够对接到Kubernetes HPA模型的监控系统,并且完全了解监控系统采集这些指标的机制,后续的自动扩缩容操作才能完成。

Kubernetes推荐尽量使用type为Object的HPA配置方式,这可以通过使用Operator模式,将外部指标通过CRD(自定义资源)定义为API资源对象来实现。

2.12.5、基于自定义指标的HPA实践

下面通过一个完整的示例,对如何搭建和使用基于自定义指标的HPA体系进行说明。

基于自定义指标进行自动扩缩容时,需要预先部署自定义Metrics Server,目前可以使用基于Prometheus、Microsoft Azure、Datadog Cluster等系统的Adapter实现自定义Metrics Server,未来还将提供基于GoogleStackdriver的实现自定义Metrics Server。读者可以参考官网https://github.com/kubernetes/metrics/blob/master/IMPLEMENTATIONS.md#custom-metrics-api的说明。

本节基于Prometheus监控系统对HPA的基础组件部署和HPA配置进行详细说明。

基于Prometheus的HPA架构如图所示。
在这里插入图片描述
关键组件包括如下。

  • Prometheus:定期采集各Pod的性能指标数据。
  • Custom Metrics Server:自定义MetricsServer,用Prometheus Adapter进行具体实现。它 从Prometheus服务采集性能指标数据,通过Kubernetes的Metrics Aggregation层将自定义指标API注册到Master的API Server中,以/apis/custom.metrics.k8s.io路径提供指标数据。
  • HPA Controller : Kubernetes的HPA控制器,基于用户定义的HorizontalPodAutoscaler进行自动扩缩容操作。

接下来对整个系统的部署过程进行说明。

  • (1)在Master的API Server启动Aggregation层,通过设置kube-apiserver服务的下列启动参数进行开启。

    • --requestheader-client-ca-file=/etc/kubernetes/ssl_keys/ca.crt:客户端CA证书。
    • --requestheader-allowed-names=:允许访问的客户端common names列表,通过header中由–requestheader- username-headers参数指定的字段获取。客户端common names的名称需要在client-ca-file中进行配置,将其设置为空值时,表示任意客户端都可以访问。
    • --requestheader-extra-headers-prefix=X-Remote-Extra-:请求头中需要检查的前缀名。
    • --requestheader-group-headers=X-Remote-Group:请求头中需要检查的组名。
    • --requestheader-username-headers=X-Remote-User:请求头中需要检查的用户名。
    • --proxy-client-cert-file=/etc/kubernetes/ssl_keys/kubelet_client.crt :在请求期间验证Aggregator的客户端CA证书。
    • --proxy-client-key-file=/etc/kubernetes/ssl_keys/kubelet_client.key:在请求期间验证Aggregator的客户端私钥。

    配置kube-controller-manager服务中HPA的相关启动参数(可选配置)如下。

    • --horizontal-pod-autoscaler-sync-period=10s:HPA控制器同步Pod副本数量的时间间隔,默认值为15s。
    • --horizontal-pod-autoscaler-downscale-stabilization=1m0s :执行缩容操作的等待时长,默认值为5min。
    • --horizontal-pod-autoscaler-initial-readiness-delay=30s:等待Pod达到Ready状态的时延,默认值为30min。
    • --horizontal-pod-autoscaler-tolerance=0.1:扩缩容计算结果的容忍度,默认值为0.1,表示[-10%-+10%]​。
  • (2)部署Prometheus,这里使用Operator模式进行部署。
    首先,使用下面的YAML配置文件部署prometheus-operator:

    apiVersion: apps/v1
    kind: Deployment             # 资源类型:Deployment 工作负载控制器
    metadata:
      labels:
        k8s-app: prometheus-operator
      name: prometheus-operator  # Deployment 名称
    spec:
      replicas: 1                # 副本数为 1
      selector:
        matchLabels:
          k8s-app: prometheus-operator
      template:
        metadata:
          labels:
            k8s-app: prometheus-operator  # Pod 模板标签,必须与 selector 匹配
        spec:
          containers:
          - image: quay.io/coreos/prometheus-operator:v0.17.0  # 镜像地址及版本
            imagePullPolicy: IfNotPresent   # 镜像拉取策略:本地存在则优先使用本地镜像
            name: prometheus-operator       # 容器名称
            ports:
            - containerPort: 8080           # 容器暴露的端口
              name: http
            resources:                      # 容器资源配额限制
              limits:
                cpu: 200m                   # CPU 上限:200 毫核
                memory: 100Mi               # 内存上限:100 MB
              requests:
                cpu: 100m                   # CPU 请求量:100 毫核
                memory: 50Mi                # 内存请求量:50 MB
    

    这个prometheus-operator会自动创建名为monitoring.coreos.com的CRD资源。

    然后,通过Operator的配置部署Prometheus服务:

    ---
    apiVersion: monitoring.coreos.com/v1
    kind: Prometheus                # 资源类型:Prometheus Operator 定义的自定义资源 (CRD)
    metadata:
      name: prometheus
      labels:
        app: prometheus
        prometheus: prometheus
    spec:
      replicas: 1                   # 副本数:1 个
      baseImage: prom/prometheus    # 使用的 Prometheus 镜像名称
      version: v2.8.0               # Prometheus 版本
      serviceMonitorSelector:
        matchLabels:
          service-monitor: function # 选择带有此标签的 ServiceMonitor 来自动发现监控目标
      resources:
        requests:
          memory: 300Mi             # 资源请求:分配至少 300Mi 内存
    
    ---
    apiVersion: v1
    kind: Service                   # 资源类型:Kubernetes Service,用于暴露 Prometheus 服务
    metadata:
      name: prometheus
      labels:
        app: prometheus
        prometheus: prometheus
    spec:
      selector:
        prometheus: prometheus      # 标签选择器:将流量转发给带有该标签的 Prometheus Pod
      ports:
      - name: http                  # 端口名称
        port: 9090                  # Service 暴露的端口(同时也是容器监听的端口)
    

    确认Prometheus Operator和Prometheus服务正常运行:

    # kubectl get pods
    NAME                                          READY   STATUS    RESTARTS   AGE
    prometheus-operator-7c976597bc-xzdf5   1/1     Running   0          51m
    prometheus-prometheus-0                   2/2     Running   0          42m
    
  • (3)部署自定义Metrics Server,这里以PrometheusAdapter的实现进行部署。下面的YAML配置文件主要包含Namespace、ConfigMap、Deployment、Service和自定义API资源custom.metrics.k8s.io/v1beta1,这里将它们部署在一个新的Namespace“custom-metrics”中。

    ---
    kind: Namespace
    apiVersion: v1
    metadata:
      name: custom-metrics
    
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: adapter-config
      namespace: custom-metrics
    data:
      config.yaml: |
        rules:
        - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod_name!=""}'
          seriesFilters: []
          resources:
            overrides:
              namespace:
                resource: namespace
              pod_name:
                resource: pod
          name:
            matches: ^container_(.*)_seconds_total$
            as: ""
          metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}[1m])) by (<<.GroupBy>>)
        - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod_name!=""}'
          seriesFilters:
          - isNot: ^container_.*_seconds_total$
          resources:
            overrides:
              namespace:
                resource: namespace
              pod_name:
                resource: pod
          name:
            matches: ^container_(.*)_total$
            as: ""
          metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}[1m])) by (<<.GroupBy>>)
        - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod_name!=""}'
          seriesFilters:
          - isNot: ^container_.*_total$
          resources:
            overrides:
              namespace:
                resource: namespace
              pod_name:
                resource: pod
          name:
            matches: ^container_(.*)$
            as: ""
          metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}) by (<<.GroupBy>>)
        - seriesQuery: '{namespace!="",__name__!~"^container_.*"}'
          seriesFilters:
          - isNot: .*_total$
          resources:
            template: <<.Resource>>
          name:
            matches: ""
            as: ""
          metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)
        - seriesQuery: '{namespace!="",__name__!~"^container_.*"}'
          seriesFilters:
          - isNot: .*_seconds_total
          resources:
            template: <<.Resource>>
          name:
            matches: ^(.*)_total$
            as: ""
          metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>)
        - seriesQuery: '{namespace!="",__name__!~"^container_.*"}'
          seriesFilters: []
          resources:
            template: <<.Resource>>
          name:
            matches: ^(.*)_seconds_total$
            as: ""
          metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>)
        resourceRules:
          cpu:
            containerQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>)
            nodeQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>, id='/'}[1m])) by (<<.GroupBy>>)
            resources:
              overrides:
                instance:
                  resource: node
                namespace:
                  resource: namespace
                pod_name:
                  resource: pod
            containerLabel: container_name
          memory:
            containerQuery: sum(container_memory_working_set_bytes{<<.LabelMatchers>>}) by (<<.GroupBy>>)
            nodeQuery: sum(container_memory_working_set_bytes{<<.LabelMatchers>>,id='/'}) by (<<.GroupBy>>)
            resources:
              overrides:
                instance:
                  resource: node
                namespace:
                  resource: namespace
                pod_name:
                  resource: pod
            containerLabel: container_name
          window: 1m
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: custom-metrics-server
      namespace: custom-metrics
      labels:
        app: custom-metrics-server
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: custom-metrics-server
      template:
        metadata:
          labels:
            app: custom-metrics-server
        spec:
          containers:
          - name: custom-metrics-server
            image: directxman12/k8s-prometheus-adapter-amd64
            imagePullPolicy: IfNotPresent
            args:
            - --prometheus-url=http://prometheus.default.svc:9090/
            - --metrics-relist-interval=30s
            - --v=10
            - --config=/etc/adapter/config.yaml
            - --logtostderr=true
            ports:
            - containerPort: 443
            securityContext:
              runAsUser: 0
            volumeMounts:
            - mountPath: /etc/adapter/
              name: config
              readOnly: true
          volumes:
          - name: config
            configMap:
              name: adapter-config
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: custom-metrics-server
      namespace: custom-metrics
    spec:
      ports:
      - port: 443
        targetPort: 443
      selector:
        app: custom-metrics-server
    
    ---
    apiVersion: apiregistration.k8s.io/v1
    kind: APIService
    metadata:
      name: v1beta1.custom.metrics.k8s.io
    spec:
      service:
        name: custom-metrics-server
        namespace: custom-metrics
      group: custom.metrics.k8s.io
      version: v1beta1
      insecureSkipTLSVerify: true
      groupPriorityMinimum: 100
      versionPriority: 100
    

    确认custom-metrics-server正常运行:

  • (4)部署应用程序,它会在HTTP URL“/metrics”路径提供名为http_requests_total的指标值:

    ---
    apiVersion: apps/v1
    kind: Deployment                # 资源类型:Deployment 工作负载控制器
    metadata:
      name: sample-app
      labels:
        app: sample-app
    spec:
      replicas: 1                   # 副本数:1 个
      selector:
        matchLabels:
          app: sample-app
      template:
        metadata:
          labels:
            app: sample-app         # Pod 模板标签,必须与 selector 匹配
        spec:
          containers:
          - image: luxas/autoscale-demo:v0.1.2  # 示例应用镜像(常用于 HPA/扩缩容测试)
            imagePullPolicy: IfNotPresent
            name: metrics-provider
            ports:
            - name: http
              containerPort: 8080   # 容器内部监听的端口
    
    ---
    apiVersion: v1
    kind: Service                   # 资源类型:Kubernetes Service,用于将流量暴露给应用
    metadata:
      name: sample-app
      labels:
        app: sample-app
    spec:
      ports:
      - name: http
        port: 80                    # Service 暴露的对外端口
        targetPort: 8080            # 转发到后端容器的端口
      selector:
        app: sample-app             # 将流量路由到带有此标签的 Pod
    

    部署成功之后,可以在应用的URL“/metrics”中查看指标http_requests_total的值:

    # kubectl get service sample-app
    NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    sample-app   ClusterIP   169.169.43.252   <none>        80/TCP    86m
    
    # curl 169.169.43.252/metrics
    # HELP http_requests_total The amount of requests served by the server in total
    # TYPE http_requests_total counter
    http_requests_total 1
    
  • (5)创建一个Prometheus的ServiceMonitor对象,用于监控应用程序提供的指标:

    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor              # 资源类型:Prometheus Operator 定义的 ServiceMonitor,用于告诉 Prometheus 如何抓取 Service 的监控指标
    metadata:
      name: sample-app                # ServiceMonitor 的名称
      labels:
        service-monitor: function     # 标签:与前面 Prometheus 资源中的 serviceMonitorSelector 对应,使其能够被自动发现
    spec:
      selector:
        matchLabels:
          app: sample-app             # 选择器:通过标签去匹配需要被监控的 Service(例如我们刚才创建的名为 sample-app 的 Service)
      endpoints:
      - port: http                    # 抓取指标的目标端口名称(对应 Service 中定义的名为 http 的端口)
    

    关键配置参数如下。

    • Selector:设置为Pod的Label“app: sample-app”​。
    • Endpoints:设置为在Service中定义的端口名称“http”​。
  • (6)创建一个HorizontalPodAutoscaler对象,用于为HPA控制器提供用户期望的自动扩缩容配置。

    apiVersion: autoscaling/v2          # 推荐使用现代的 autoscaling/v2 API 版本
    kind: HorizontalPodAutoscaler     # 资源类型:水平 Pod 自动扩缩容控制器
    metadata:
      name: sample-app                # HPA 的名称
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment              # 目标控制器类型(这里是 Deployment)
        name: sample-app              # 目标 Deployment 的名称
      minReplicas: 1                  # 最小 Pod 副本数
      maxReplicas: 10                 # 最大 Pod 副本数
      metrics:                        # 扩缩容监控指标
      - type: Pods                    # 指标类型:Pods 指标(针对所有 Pod 的自定义指标计算平均值)
        pods:
          metric:
            name: http_requests       # 自定义指标名称(例如每个 Pod 的 HTTP 请求数)
          target:
            type: AverageValue        # 目标类型:平均值类型
            averageValue: 500m        # 目标阈值:当每个 Pod 的平均请求数达到 500m(即 0.5,或每秒 0.5 个请求,视具体适配器定义而定)时触发扩容
    

    关键配置参数如下。

    • scaleTargetRef:设置HPA的作用对象为之前部署的Deployment“sample-app”​。
    • type=Pods:设置指标类型为Pods,表示从Pod获取指标数据。
    • metric.name=http_requests:将指标的名称设置为“http_requests”​,是自定义Metrics Server将应用程序提供的指标“http_requests_total”经过计算转换成的一个新比率值,即sum(rate(http_requests_total{namespace=“xx”,pod=“xx”}[1m])) by pod,指过去1min内全部Pod指标http_requests_total总和的每秒平均值。
    • target:将指标http_requests的目标值设置为500m,类型为AverageValue,表示基于全部Pod副本数据计算平均值。目标Pod副本数量将使用公式“http_requests当前值/500m”进行计算。
    • minReplicas和maxReplicas:将扩缩容区间设置为1~10(单位是Pod副本)​。

    此时可以通过查看自定义Metrics Server提供的URL“custom.metrics.k8s.io/v1beta1”查看Pod的指标是否已经被成功采集,并能够通过聚合API进行查询:

    # kubectl get --raw
    "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests?sel
    ector=app%3Dsample-app"
    {"kind":"MetricValueList","apiVersion":"custom.metrics.k8s.io/v1beta1","meta
    data":{"selfLink":"/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%
    2A/http_requests"},"items":[{"describedObject":{"kind":"Pod","namespace":"defaul
    t","name":"sample-app-579f977995-jz98h","apiVersion":"/v1"},"metricName":"http_r
    equests","timestamp":"2019-03-16T17:54:38Z","value":"33m"}]}
    

    从结果中看到正确的value值,说明自定义Metrics Server工作正常。

    查看HorizontalPodAutoscaler的详细信息,可以看到其成功从自定义Metrics Server处获取了应用的指标数据,可以进行扩缩容操作:

    # kubectl describe hpa.v2beta2.autoscaling sample-app
    Name:                       sample-app
    Namespace:                  default
    Labels:                     <none>
    Annotations:                <none>
    CreationTimestamp:          Sun, 17 Mar 2019 01:05:33 +0800
    Reference:                  Deployment/sample-app
    Metrics:                    ( current / target )
      "http_requests" on pods:  33m / 500m
    Min replicas:               1
    Max replicas:               10
    Deployment pods:            1 current / 1 desired
    Conditions:
      Type            Status  Reason              Message
      ----            ------  ------              -------
      AbleToScale     True   ReadyForNewScale    recommended size matches current
    size
      ScalingActive   True   ValidMetricFound    the HPA was able to successfully
    calculate a replica count from pods metric http_requests
      ScalingLimited  False   DesiredWithinRange  the desired count is within the
    acceptable range
    
  • (7)对应用的服务地址发起HTTP访问请求,验证HPA自动扩容机制。例如,可以使用如下脚本对应用进行压力测试:

    # for i in {1..100000}; do wget -q -O-169.169.43.252 > /dev/null; done
    

    一段时间之后,观察HorizontalPodAutoscaler和Pod数量的变化,可以看到自动扩容的过程:

    # kubectl describe hpa.v2beta2.autoscaling sample-app
    Name:                       sample-app
    Namespace:                  default
    Labels:                     <none>
    Annotations:                <none>
    CreationTimestamp:          Sun, 17 Mar 2019 02:01:30 +0800
    Reference:                  Deployment/sample-app
    Metrics:                    ( current / target )
      "http_requests" on pods:  4296m / 500m
    Min replicas:               1
    Max replicas:               10
    Deployment pods:            10 current / 10 desired
    Conditions:
      Type            Status  Reason               Message
      ----            ------  ------               -------
      AbleToScale     True    ScaleDownStabilized  recent recommendations were
    higher than current one, applying the highest recent recommendation
      ScalingActive   True    ValidMetricFound     the HPA was able to successfully
    calculate a replica count from pods metric http_requests
      ScalingLimited  True    TooManyReplicas      the desired replica count is more
    than the maximum replica count
    Events:
      Type     Reason             Age   From                       Message
      ----     ------             ----  ----                       -------
      Normal   SuccessfulRescale  67s   horizontal-pod-autoscaler  New size: 4;
    reason: pods metric http_requests above target
      Normal   SuccessfulRescale  56s   horizontal-pod-autoscaler  New size: 8;
    reason: pods metric http_requests above target
      Normal   SuccessfulRescale  45s   horizontal-pod-autoscaler  New size: 10;
    reason: pods metric http_requests above target
    

    发现Pod数量扩容到了10个(被maxReplicas参数限制的最大值)​:

    # kubectl get pods -l app=sample-app
    NAME                                    READY   STATUS    RESTARTS   AGE
    sample-app-579f977995-dtgcw            1/1     Running   0          32s
    sample-app-579f977995-hn5bd            1/1     Running   0          70s
    sample-app-579f977995-jz98h            1/1     Running   0          75s
    sample-app-579f977995-kllhq            1/1     Running   0          90s
    sample-app-579f977995-p5d44            1/1     Running   0          85s
    sample-app-579f977995-q6rxb            1/1     Running   0          70s
    sample-app-579f977995-rhn5d            1/1     Running   0          70s
    sample-app-579f977995-tjc8q            1/1     Running   0          86s
    sample-app-579f977995-tzthf            1/1     Running   0          70s
    sample-app-579f977995-wswcx            1/1     Running   0          32s
    

    停止访问应用服务,等待一段时间后,观察HorizontalPodAutoscaler和Pod数量的变化,可以看到缩容操作:

    # kubectl describe hpa.v2beta2.autoscaling sample-app
    Name:                       sample-app
    Namespace:                  default
    Labels:                     <none>
    Annotations:                <none>
    CreationTimestamp:          Sun, 17 Mar 2019 02:01:30 +0800
    Reference:                  Deployment/sample-app
    Metrics:                    ( current / target )
      "http_requests" on pods:  33m / 500m
    Min replicas:               1
    Max replicas:               10
    Deployment pods:            1 current / 1 desired
    Conditions:
      Type            Status  Reason              Message
      ----            ------  ------              -------
      AbleToScale     True    ReadyForNewScale    recommended size matches current
    size
      ScalingActive   True    ValidMetricFound    the HPA was able to successfully
    calculate a replica count from pods metric http_requests
      ScalingLimited  False   DesiredWithinRange  the desired count is within the
    acceptable range
    Events:
      Type     Reason             Age    From                       Message
      ----     ------             ----   ----                       -------
      Normal   SuccessfulRescale  6m48s  horizontal-pod-autoscaler  New size: 4;
    reason: pods metric http_requests above target
      Normal   SuccessfulRescale  6m37s  horizontal-pod-autoscaler  New size: 8;
    reason: pods metric http_requests above target
      Normal   SuccessfulRescale  6m26s  horizontal-pod-autoscaler  New size: 10;
    reason: pods metric http_requests above target
      Normal   SuccessfulRescale  47s    horizontal-pod-autoscaler  New size: 1;
    reason: All metrics below target
    

    发现Pod的数量已经缩容到最小值1个:

    # kubectl get pods -l app=sample-app
    NAME                                    READY   STATUS    RESTARTS   AGE
    sample-app-579f977995-dtgcw            1/1     Running   0          10m
    
深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值