# Notebook from swillems/ion_networks
Path: ion_networks/sandbox_lfq.ipynb

<code>
import os
import importlib
from timeit import timeit
import logging
import sys
import importlib
import time
import multiprocessing as mp
import multiprocessing.pool

import numpy as np
import pandas as pd
import scipy
import h5py
import matplotlib
from matplotlib import pyplot as plt
import seaborn as sns
import numba
import sklearn.linear_model

import ms_utils
import browser
import interface
import ms_database
import ms_run_files

import sandbox

import line_profiler
profile = line_profiler.LineProfiler()
# heat.evolve = profile(heat.evolve)
# profile.print_stats()

def reload():
    importlib.reload(ms_run_files)
    importlib.reload(ms_utils)
    importlib.reload(browser)
    importlib.reload(interface)
    importlib.reload(sandbox)
    importlib.reload(ms_database)
   _____no_output_____evi = ms_run_files.HDF_Evidence_File("/home/sander/Documents/Proteomics/data/ecoli/28Oct2016_060.inet.csv")
inet = evi.ion_network_____no_output_____positive_edges = evi.get_edges()
negative_edges = evi.get_edges(positive=False)_____no_output_____indptr, indices, edge_pointers = inet.get_edges(symmetric=True, return_pointers=True)_____no_output_____evi.create_mgf(
    {
        "log_file_name": ".",
        "output_directory": ".",
        "force_overwrite": True,
        "minimum_peaks": 5,
        "edge_threshold": "2 * (positive_edges - negative_edges) > evidence_run_count"
    }
)_____no_output_____@numba.njit
def cluster(
    indptr,
    indices,
    selected_edges,
    edge_pointers,
):
    node_count = indptr.shape[0] - 1
    clusters = np.zeros(node_count, np.int64)
    cluster_number = 0
    for index in range(node_count):
        if clusters[index] != 0:
            continue
        current_cluster = set()
        new_indices = set()
        new_indices.add(index)
        while len(new_indices) > 0:
            new_index = new_indices.pop()
            current_cluster.add(new_index)
            neighbors = indices[indptr[new_index]: indptr[new_index + 1]]
            pointers = edge_pointers[indptr[new_index]: indptr[new_index + 1]]
            selected = selected_edges[pointers]
            new_indices |= set(neighbors[selected]) - current_cluster
        cluster_number += 1
        for i in current_cluster:
            clusters[i] = cluster_number
    return clusters_____no_output_____clusters = cluster(
    indptr,
    indices,
    (positive_edges - negative_edges) > 5,
#     positive_edges==evi.run_count,
    edge_pointers,
)
cluster_sizes = np.bincount(clusters)_____no_output_____( positive_edges==evi.run_count).shape, indices.shape, edge_pointers.shape[0]/2_____no_output_____%matplotlib notebook

plt.plot(np.cumsum(np.bincount(cluster_sizes)[::-1])[::-1], marker=".")_____no_output_____def write_to_mgf(
    inet,
    clusters,
    file_name,
    minsize,
    expand,
    indptr,
    indices,
    selected_edges,
    edge_pointers,
):
    cluster_indices = np.argsort(clusters)
    cluster_indptr = np.empty(np.max(clusters + 2), np.int64)
    cluster_indptr[0] = 0
    cluster_indptr[1:] = np.cumsum(np.bincount(clusters))
    mzs, ints, rts = inet.get_ion_coordinates(["FRAGMENT_MZ", "FRAGMENT_LOGINT", "PRECURSOR_RT"])
    with open(file_name, "w") as infile:
        for cluster_index in np.flatnonzero(np.diff(cluster_indptr) > 10):
            infile.write("BEGIN IONS\n")
            cluster = cluster_indices[cluster_indptr[cluster_index]: cluster_indptr[cluster_index + 1]]
            if expand:
                cluster = expand_cluster(
                    cluster,
                    indptr,
                    indices,
                    selected_edges,
                    edge_pointers,
                )
            local_mzs = np.round(mzs[cluster], 4)
            local_ints = np.round(2**ints[cluster], 2)
            local_rts = rts[cluster]
#             infile.write(
#                 f"TITLE=cluster_index_{cluster_index}_size_{cluster.shape[0]}\n"
#             )
            infile.write(
                f"TITLE=cluster_index.{cluster_index}.{cluster_index}. "
                f"File=\"{inet.file_name}\" "
                f"NativeID:\"sample=1 period=1 cycle={cluster_index-1} experiment=1\"\n"
            )
            infile.write(
                f"RTINSECONDS={np.round(np.average(local_rts) * 60, 2)}\n"
            )
            infile.write("PEPMASS=1000\n")
            infile.write("CHARGE=2+\n")
            mz_order = np.argsort(local_mzs)
            for i in mz_order:
                infile.write(f"{local_mzs[i]} {local_ints[i]}\n")
            infile.write("END IONS\n")

# @numba.njit
def expand_cluster(
    cluster,
    indptr,
    indices,
    selected_edges,
    edge_pointers,
):
    new_indices = [cluster]
    for index in cluster:
        neighbors = indices[indptr[index]: indptr[index + 1]]
        pointers = edge_pointers[indptr[index]: indptr[index + 1]]
        selected = selected_edges[pointers]
        new_indices.append(neighbors[selected])
    return np.unique(np.concatenate(new_indices))_____no_output_____write_to_mgf(
    inet=inet,
    clusters=clusters,
    file_name="/home/sander/Documents/Sandbox/test_msfragger/test.mgf",
    minsize=5,
    expand=False,
    indptr=indptr,
    indices=indices,
    selected_edges=(positive_edges - negative_edges) > 3,
    edge_pointers=edge_pointers,
)_____no_output_____db = ms_database.HDF_Database_File(
    "/home/sander/Documents/Proteomics/data/databases/crap_ecoli_concatenated_decoy.hdf"
)
sequences = db.read_dataset("sequence", "proteins")
proteins = db.read_dataset("protein", "proteins")
with open("/home/sander/Documents/Sandbox/test_msfragger/ecoli_with_decoy.fasta", "w") as infile:
    for seq, prot in zip(sequences, proteins):
        infile.write(f">{prot}\n")
        infile.write(f"{seq}\n")_____no_output_____pmzs = inet.get_ion_coordinates("PRECURSOR_MZ")_____no_output_____pmzs[np.flatnonzero(clusters==988762)]_____no_output_____in_folder = "/home/sander/projects/tenzer"
evis = {}
inets = {}
for file_name in sorted(os.listdir(in_folder)):
    if file_name.endswith(".evidence.hdf"):
        in_file_name = os.path.join(in_folder, file_name)
        evi = ms_run_files.Evidence(in_file_name)
        run_name = evi.run_name
        evis[run_name] = evi
        inet = evi.ion_network
        inets[run_name] = inet

self_run = sorted(inets)[0]
self_inet = inets[self_run]
self_evi = evis[self_run]_____no_output_____# reproducibility_counts = self_evi.get_nodes()
# alignment_indices = [
#      np.flatnonzero(reproducibility_counts == i) for i in range(1 + self_evi.run_count)
# ]
# alignments = [
#     np.empty(
#         (alignment_indices[i].shape[0], i), np.int64
#     ) for i in range(1 + self_evi.run_count)
# ]
# alignment_masks = [
#     np.empty(
#         (alignment_indices[i].shape[0], i), np.bool_
#     ) for i in range(1 + self_evi.run_count)
# ]

alignment_matrix = np.empty(
    (self_inet.node_count, self_evi.run_count), np.int64
)
alignment_matrix_mask = np.zeros(
    (self_inet.node_count, self_evi.run_count), np.bool_
)
alignment_matrix_intensities = np.zeros(
    (self_inet.node_count, self_evi.run_count), np.float64
)

for index, (other_run, other_evi) in enumerate(sorted(evis.items())[1:]):
    self_ali = self_evi.get_nodes(other_evi)
    other_ali = other_evi.get_nodes(self_evi)
    alignment_matrix[self_ali, index] = other_ali
    alignment_matrix_mask[self_ali, index] = True
    alignment_matrix_intensities[self_ali, index] = 2**other_evi.ion_network.get_ion_coordinates(
        "FRAGMENT_LOGINT",
        other_ali
    )_____no_output_____a_reproducibility = 1 + np.sum(alignment_matrix_mask[:, 1::2], axis=1)
b_reproducibility = np.sum(alignment_matrix_mask[:, ::2], axis=1)
total_reproducibility = a_reproducibility + b_reproducibility

b_intensities = np.sum(alignment_matrix_intensities[:, ::2], axis=1) / b_reproducibility
a_intensities = (
    2**self_inet.get_ion_coordinates(
        "FRAGMENT_LOGINT"
    ) + np.sum(alignment_matrix_intensities[:, 1::2], axis=1)
) /  a_reproducibility

logfcs = np.log2(a_intensities) - np.log2(b_intensities)
valid_logfcs = (a_reproducibility > 0) & (b_reproducibility > 0)_____no_output_____%matplotlib notebook

for i in range(2, 1 + 10):
    reps = logfcs[valid_logfcs & (total_reproducibility == i)]
    a, b = np.unique(np.round(reps, 1), return_counts=True)
    plt.plot(a, b / np.sum(b), marker=".")

plt.xlim((-2, 2))
plt.xlabel("LOGFC")
plt.ylabel("relative frequency")
plt.legend(range(2, 1 + 10))_____no_output_____ecoli = logfcs < -0.5
yeast = logfcs > 0.2_____no_output_____left_indices, right_indices = self_inet.get_edges(
    return_as_pairs=True,
)
positive_counts = self_evi.get_edges()
negative_counts = self_evi.get_edges(positive=False)
left_overlaps = alignment_matrix_mask[left_indices]
right_overlaps = alignment_matrix_mask[right_indices]
overlaps = np.sum(left_overlaps&right_overlaps, axis=1)
logfc_deviations = np.abs(
    logfcs[left_indices] - logfcs[right_indices]
)_____no_output_____# evidence = (
#     positive_counts - negative_counts
# ) / (
#     positive_counts + negative_counts
# ) * positive_counts

evidence = positive_counts - negative_counts_____no_output_____overlap = 4
# int_filter = 1000
# logints = self_inet.get_ion_coordinates("FRAGMENT_LOGINT")
selected_edges = overlaps == overlap
# selected_edges &= (logints[left_indices] < int_filter)  & (logints[right_indices] < int_filter)

selected_left_indices = left_indices[selected_edges]
selected_right_indices = right_indices[selected_edges]
selected_evidence = evidence[selected_edges]
selected_nan_values = np.isnan(selected_evidence)
selected_nan_values |= np.isinf(selected_evidence)
selected_evidence_values = np.unique(selected_evidence[~selected_nan_values])

selected_logfc_deviations = logfc_deviations[selected_edges]_____no_output_____%matplotlib notebook

color_mapper = matplotlib.cm.ScalarMappable(
    norm=matplotlib.colors.Normalize(
        vmin=np.min(selected_evidence_values),
        vmax=np.max(selected_evidence_values),
    ),
    cmap="RdYlGn"
)

random_right_indices = selected_right_indices.copy()
np.random.seed(100)
np.random.shuffle(random_right_indices)
random_logfc_deviation = np.abs(logfcs[selected_left_indices] - logfcs[random_right_indices])
nan_values = np.isnan(random_logfc_deviation)
nan_values |= np.isinf(random_logfc_deviation)
random_logfc_deviation = random_logfc_deviation[~nan_values]
plt.plot(
    np.percentile(random_logfc_deviation, range(101)),
    np.arange(101)/100,
    linestyle="dotted",
    c="black"
)

for evidence_value in selected_evidence_values:
    current = selected_evidence == evidence_value
    logfc_deviation = selected_logfc_deviations[current]
    nan_values = np.isnan(logfc_deviation)
    nan_values |= np.isinf(logfc_deviation)
    logfc_deviation = logfc_deviation[~nan_values]
    plt.plot(
        np.percentile(logfc_deviation, range(101)),# - np.percentile(random_logfc_deviation, range(101)),
        np.arange(101)/100,
        c=color_mapper.to_rgba(evidence_value)
    )

plt.axvline(
    np.median(random_logfc_deviation),
    linestyle="dotted",
    c="grey"
)
# plt.legend(list(np.round(evidence_values, 1)) + ["RANDOM"])
plt.colorbar(color_mapper)
plt.xlabel("ABSOLUTE LOGFC DEVIATION ON EDGE")
plt.ylabel("Relative frequency")
plt.title("EDGE EVIDENCE BETWEEN FULLY REPRODUCIBLE NODES")_____no_output_____%matplotlib notebook

color_mapper = matplotlib.cm.ScalarMappable(
    norm=matplotlib.colors.Normalize(
        vmin=np.min(0),
        vmax=np.max(self_evi.run_count),
    ),
    cmap="RdYlGn"
)

# for overlap in range(1, self_evi.run_count):
#     selected_edges = overlaps == overlap
if True:
    selected_edges = overlaps >= 1
    # selected_edges &= ecoli[left_indices] | ecoli[right_indices]

    selected_left_indices = left_indices[selected_edges]
    selected_right_indices = right_indices[selected_edges]
    selected_evidence = evidence[selected_edges]
    selected_nan_values = np.isnan(selected_evidence)
    selected_nan_values |= np.isinf(selected_evidence)
    selected_evidence_values = np.unique(selected_evidence[~selected_nan_values])

    ecoli_hit_rates = np.empty(selected_evidence_values.shape[0], np.float64)
    yeast_hit_rates = np.empty(selected_evidence_values.shape[0], np.float64)
    ecoli_random_rates = np.empty(selected_evidence_values.shape[0], np.float64)
    yeast_random_rates = np.empty(selected_evidence_values.shape[0], np.float64)
#     total_count = np.sum(selected_edges)
    for i, evidence_value in enumerate(selected_evidence_values):
        current = selected_evidence == evidence_value
        total_count = np.sum(current)

        left_ecoli = ecoli[selected_left_indices[current]]
        right_ecoli = ecoli[selected_right_indices[current]]
        ecoli_hit_rate = np.sum(left_ecoli & right_ecoli) / np.sum(left_ecoli | right_ecoli)
        ecoli_hit_rates[i] = ecoli_hit_rate
        random_right_ecoli = right_ecoli.copy()
        np.random.shuffle(random_right_ecoli)
        ecoli_random_rate = np.sum(left_ecoli & random_right_ecoli) / np.sum(left_ecoli | random_right_ecoli)
        ecoli_random_rates[i] = ecoli_random_rate

        left_yeast = yeast[selected_left_indices[current]]
        right_yeast = yeast[selected_right_indices[current]]
        yeast_hit_rate = np.sum(left_yeast & right_yeast) / np.sum(left_yeast | right_yeast)
        yeast_hit_rates[i] = yeast_hit_rate
        random_right_yeast = right_yeast.copy()
        np.random.shuffle(random_right_yeast)
        yeast_random_rate = np.sum(left_yeast & random_right_yeast) / np.sum(left_yeast | random_right_yeast)
        yeast_random_rates[i] = yeast_random_rate

    plt.plot(
        selected_evidence_values,
        ecoli_hit_rates,
        marker=".",
        c=color_mapper.to_rgba(overlap)
    )
    plt.plot(
        selected_evidence_values,
        ecoli_random_rates,
        marker=".",
        c=color_mapper.to_rgba(overlap),
        linestyle="dotted",
    )
    plt.plot(
        selected_evidence_values,
        yeast_hit_rates,
        marker=".",
        c=color_mapper.to_rgba(overlap)
    )
    plt.plot(
        selected_evidence_values,
        yeast_random_rates,
        marker=".",
        c=color_mapper.to_rgba(overlap),
        linestyle="dotted",
    )

# plt.axvline(
#     np.median(random_logfc_deviation),
#     linestyle="dotted",
#     c="grey"
# )
# # plt.legend(list(np.round(evidence_values, 1)) + ["RANDOM"])
plt.colorbar(color_mapper)
# plt.xlabel("ABSOLUTE LOGFC DEVIATION ON EDGE")
plt.ylabel("Relative frequency")
# plt.title("EDGE EVIDENCE BETWEEN FULLY REPRODUCIBLE NODES")_____no_output_____
</code>


# Notebook from StanleySongPro/Dive-into-DL-PyTorch
Path: code/chapter05_CNN/5.5_lenet.ipynb

# 5.5 卷积神经网络(LeNet)_____no_output_____

<code>
import os
import time
import torch
from torch import nn, optim

import sys
sys.path.append("..")
import d2lzh_pytorch as d2l

os.environ["CUDA_VISIBLE_DEVICES"] = "0"
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

print(torch.__version__)
print(device)1.9.0
cpu
help(nn.Conv2d)Help on class Conv2d in module torch.nn.modules.conv:

class Conv2d(_ConvNd)
 |  Conv2d(in_channels: int, out_channels: int, kernel_size: Union[int, Tuple[int, int]], stride: Union[int, Tuple[int, int]] = 1, padding: Union[str, int, Tuple[int, int]] = 0, dilation: Union[int, Tuple[int, int]] = 1, groups: int = 1, bias: bool = True, padding_mode: str = 'zeros', device=None, dtype=None) -> None
 |
 |  Applies a 2D convolution over an input signal composed of several input
 |  planes.
 |
 |  In the simplest case, the output value of the layer with input size
 |  :math:`(N, C_{\text{in}}, H, W)` and output :math:`(N, C_{\text{out}}, H_{\text{out}}, W_{\text{out}})`
 |  can be precisely described as:
 |
 |  .. math::
 |      \text{out}(N_i, C_{\text{out}_j}) = \text{bias}(C_{\text{out}_j}) +
 |      \sum_{k = 0}^{C_{\text{in}} - 1} \text{weight}(C_{\text{out}_j}, k) \star \text{input}(N_i, k)
 |
 |
 |  where :math:`\star` is the valid 2D `cross-correlation`_ operator,
 |  :math:`N` is a batch size, :math:`C` denotes a number of channels,
 |  :math:`H` is a height of input planes in pixels, and :math:`W` is
 |  width in pixels.
 |
 |
 |  This module supports :ref:`TensorFloat32<tf32_on_ampere>`.
 |
 |  * :attr:`stride` controls the stride for the cross-correlation, a single
 |    number or a tuple.
 |
 |  * :attr:`padding` controls the amount of padding applied to the input. It
 |    can be either a string {'valid', 'same'} or a tuple of ints giving the
 |    amount of implicit padding applied on both sides.
 |
 |  * :attr:`dilation` controls the spacing between the kernel points; also
 |    known as the à trous algorithm. It is harder to describe, but this `link`_
 |    has a nice visualization of what :attr:`dilation` does.
 |
 |  * :attr:`groups` controls the connections between inputs and outputs.
 |    :attr:`in_channels` and :attr:`out_channels` must both be divisible by
 |    :attr:`groups`. For example,
 |
 |      * At groups=1, all inputs are convolved to all outputs.
 |      * At groups=2, the operation becomes equivalent to having two conv
 |        layers side by side, each seeing half the input channels
 |        and producing half the output channels, and both subsequently
 |        concatenated.
 |      * At groups= :attr:`in_channels`, each input channel is convolved with
 |        its own set of filters (of size
 |        :math:`\frac{\text{out\_channels}}{\text{in\_channels}}`).
 |
 |  The parameters :attr:`kernel_size`, :attr:`stride`, :attr:`padding`, :attr:`dilation` can either be:
 |
 |      - a single ``int`` -- in which case the same value is used for the height and width dimension
 |      - a ``tuple`` of two ints -- in which case, the first `int` is used for the height dimension,
 |        and the second `int` for the width dimension
 |
 |  Note:
 |      When `groups == in_channels` and `out_channels == K * in_channels`,
 |      where `K` is a positive integer, this operation is also known as a "depthwise convolution".
 |
 |      In other words, for an input of size :math:`(N, C_{in}, L_{in})`,
 |      a depthwise convolution with a depthwise multiplier `K` can be performed with the arguments
 |      :math:`(C_\text{in}=C_\text{in}, C_\text{out}=C_\text{in} \times \text{K}, ..., \text{groups}=C_\text{in})`.
 |
 |  Note:
 |      In some circumstances when given tensors on a CUDA device and using CuDNN, this operator may select a nondeterministic algorithm to increase performance. If this is undesirable, you can try to make the operation deterministic (potentially at a performance cost) by setting ``torch.backends.cudnn.deterministic = True``. See :doc:`/notes/randomness` for more information.
 |
 |  Note:
 |      ``padding='valid'`` is the same as no padding. ``padding='same'`` pads
 |      the input so the output has the shape as the input. However, this mode
 |      doesn't support any stride values other than 1.
 |
 |  Args:
 |      in_channels (int): Number of channels in the input image
 |      out_channels (int): Number of channels produced by the convolution
 |      kernel_size (int or tuple): Size of the convolving kernel
 |      stride (int or tuple, optional): Stride of the convolution. Default: 1
 |      padding (int, tuple or str, optional): Padding added to all four sides of
 |          the input. Default: 0
 |      padding_mode (string, optional): ``'zeros'``, ``'reflect'``,
 |          ``'replicate'`` or ``'circular'``. Default: ``'zeros'``
 |      dilation (int or tuple, optional): Spacing between kernel elements. Default: 1
 |      groups (int, optional): Number of blocked connections from input
 |          channels to output channels. Default: 1
 |      bias (bool, optional): If ``True``, adds a learnable bias to the
 |          output. Default: ``True``
 |
 |
 |  Shape:
 |      - Input: :math:`(N, C_{in}, H_{in}, W_{in})`
 |      - Output: :math:`(N, C_{out}, H_{out}, W_{out})` where
 |
 |        .. math::
 |            H_{out} = \left\lfloor\frac{H_{in}  + 2 \times \text{padding}[0] - \text{dilation}[0]
 |                      \times (\text{kernel\_size}[0] - 1) - 1}{\text{stride}[0]} + 1\right\rfloor
 |
 |        .. math::
 |            W_{out} = \left\lfloor\frac{W_{in}  + 2 \times \text{padding}[1] - \text{dilation}[1]
 |                      \times (\text{kernel\_size}[1] - 1) - 1}{\text{stride}[1]} + 1\right\rfloor
 |
 |  Attributes:
 |      weight (Tensor): the learnable weights of the module of shape
 |          :math:`(\text{out\_channels}, \frac{\text{in\_channels}}{\text{groups}},`
 |          :math:`\text{kernel\_size[0]}, \text{kernel\_size[1]})`.
 |          The values of these weights are sampled from
 |          :math:`\mathcal{U}(-\sqrt{k}, \sqrt{k})` where
 |          :math:`k = \frac{groups}{C_\text{in} * \prod_{i=0}^{1}\text{kernel\_size}[i]}`
 |      bias (Tensor):   the learnable bias of the module of shape
 |          (out_channels). If :attr:`bias` is ``True``,
 |          then the values of these weights are
 |          sampled from :math:`\mathcal{U}(-\sqrt{k}, \sqrt{k})` where
 |          :math:`k = \frac{groups}{C_\text{in} * \prod_{i=0}^{1}\text{kernel\_size}[i]}`
 |
 |  Examples:
 |
 |      >>> # With square kernels and equal stride
 |      >>> m = nn.Conv2d(16, 33, 3, stride=2)
 |      >>> # non-square kernels and unequal stride and with padding
 |      >>> m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
 |      >>> # non-square kernels and unequal stride and with padding and dilation
 |      >>> m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
 |      >>> input = torch.randn(20, 16, 50, 100)
 |      >>> output = m(input)
 |
 |  .. _cross-correlation:
 |      https://en.wikipedia.org/wiki/Cross-correlation
 |
 |  .. _link:
 |      https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md
 |
 |  Method resolution order:
 |      Conv2d
 |      _ConvNd
 |      torch.nn.modules.module.Module
 |      builtins.object
 |
 |  Methods defined here:
 |
 |  __init__(self, in_channels: int, out_channels: int, kernel_size: Union[int, Tuple[int, int]], stride: Union[int, Tuple[int, int]] = 1, padding: Union[str, int, Tuple[int, int]] = 0, dilation: Union[int, Tuple[int, int]] = 1, groups: int = 1, bias: bool = True, padding_mode: str = 'zeros', device=None, dtype=None) -> None
 |      Initializes internal Module state, shared by both nn.Module and ScriptModule.
 |
 |  forward(self, input: torch.Tensor) -> torch.Tensor
 |      Defines the computation performed at every call.
 |
 |      Should be overridden by all subclasses.
 |
 |      .. note::
 |          Although the recipe for forward pass needs to be defined within
 |          this function, one should call the :class:`Module` instance afterwards
 |          instead of this since the former takes care of running the
 |          registered hooks while the latter silently ignores them.
 |
 |  ----------------------------------------------------------------------
 |  Methods inherited from _ConvNd:
 |
 |  __setstate__(self, state)
 |
 |  extra_repr(self)
 |      Set the extra representation of the module
 |
 |      To print customized extra information, you should re-implement
 |      this method in your own modules. Both single-line and multi-line
 |      strings are acceptable.
 |
 |  reset_parameters(self) -> None
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from _ConvNd:
 |
 |  __annotations__ = {'_in_channels': <class 'int'>, '_reversed_padding_r...
 |
 |  __constants__ = ['stride', 'padding', 'dilation', 'groups', 'padding_m...
 |
 |  ----------------------------------------------------------------------
 |  Methods inherited from torch.nn.modules.module.Module:
 |
 |  __call__ = _call_impl(self, *input, **kwargs)
 |
 |  __delattr__(self, name)
 |      Implement delattr(self, name).
 |
 |  __dir__(self)
 |      Default dir() implementation.
 |
 |  __getattr__(self, name: str) -> Union[torch.Tensor, ForwardRef('Module')]
 |
 |  __repr__(self)
 |      Return repr(self).
 |
 |  __setattr__(self, name: str, value: Union[torch.Tensor, ForwardRef('Module')]) -> None
 |      Implement setattr(self, name, value).
 |
 |  add_module(self, name: str, module: Union[ForwardRef('Module'), NoneType]) -> None
 |      Adds a child module to the current module.
 |
 |      The module can be accessed as an attribute using the given name.
 |
 |      Args:
 |          name (string): name of the child module. The child module can be
 |              accessed from this module using the given name
 |          module (Module): child module to be added to the module.
 |
 |  apply(self: ~T, fn: Callable[[ForwardRef('Module')], NoneType]) -> ~T
 |      Applies ``fn`` recursively to every submodule (as returned by ``.children()``)
 |      as well as self. Typical use includes initializing the parameters of a model
 |      (see also :ref:`nn-init-doc`).
 |
 |      Args:
 |          fn (:class:`Module` -> None): function to be applied to each submodule
 |
 |      Returns:
 |          Module: self
 |
 |      Example::
 |
 |          >>> @torch.no_grad()
 |          >>> def init_weights(m):
 |          >>>     print(m)
 |          >>>     if type(m) == nn.Linear:
 |          >>>         m.weight.fill_(1.0)
 |          >>>         print(m.weight)
 |          >>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
 |          >>> net.apply(init_weights)
 |          Linear(in_features=2, out_features=2, bias=True)
 |          Parameter containing:
 |          tensor([[ 1.,  1.],
 |                  [ 1.,  1.]])
 |          Linear(in_features=2, out_features=2, bias=True)
 |          Parameter containing:
 |          tensor([[ 1.,  1.],
 |                  [ 1.,  1.]])
 |          Sequential(
 |            (0): Linear(in_features=2, out_features=2, bias=True)
 |            (1): Linear(in_features=2, out_features=2, bias=True)
 |          )
 |          Sequential(
 |            (0): Linear(in_features=2, out_features=2, bias=True)
 |            (1): Linear(in_features=2, out_features=2, bias=True)
 |          )
 |
 |  bfloat16(self: ~T) -> ~T
 |      Casts all floating point parameters and buffers to ``bfloat16`` datatype.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Returns:
 |          Module: self
 |
 |  buffers(self, recurse: bool = True) -> Iterator[torch.Tensor]
 |      Returns an iterator over module buffers.
 |
 |      Args:
 |          recurse (bool): if True, then yields buffers of this module
 |              and all submodules. Otherwise, yields only buffers that
 |              are direct members of this module.
 |
 |      Yields:
 |          torch.Tensor: module buffer
 |
 |      Example::
 |
 |          >>> for buf in model.buffers():
 |          >>>     print(type(buf), buf.size())
 |          <class 'torch.Tensor'> (20L,)
 |          <class 'torch.Tensor'> (20L, 1L, 5L, 5L)
 |
 |  children(self) -> Iterator[ForwardRef('Module')]
 |      Returns an iterator over immediate children modules.
 |
 |      Yields:
 |          Module: a child module
 |
 |  cpu(self: ~T) -> ~T
 |      Moves all model parameters and buffers to the CPU.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Returns:
 |          Module: self
 |
 |  cuda(self: ~T, device: Union[int, torch.device, NoneType] = None) -> ~T
 |      Moves all model parameters and buffers to the GPU.
 |
 |      This also makes associated parameters and buffers different objects. So
 |      it should be called before constructing optimizer if the module will
 |      live on GPU while being optimized.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Args:
 |          device (int, optional): if specified, all parameters will be
 |              copied to that device
 |
 |      Returns:
 |          Module: self
 |
 |  double(self: ~T) -> ~T
 |      Casts all floating point parameters and buffers to ``double`` datatype.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Returns:
 |          Module: self
 |
 |  eval(self: ~T) -> ~T
 |      Sets the module in evaluation mode.
 |
 |      This has any effect only on certain modules. See documentations of
 |      particular modules for details of their behaviors in training/evaluation
 |      mode, if they are affected, e.g. :class:`Dropout`, :class:`BatchNorm`,
 |      etc.
 |
 |      This is equivalent with :meth:`self.train(False) <torch.nn.Module.train>`.
 |
 |      See :ref:`locally-disable-grad-doc` for a comparison between
 |      `.eval()` and several similar mechanisms that may be confused with it.
 |
 |      Returns:
 |          Module: self
 |
 |  float(self: ~T) -> ~T
 |      Casts all floating point parameters and buffers to ``float`` datatype.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Returns:
 |          Module: self
 |
 |  get_buffer(self, target: str) -> 'Tensor'
 |      Returns the buffer given by ``target`` if it exists,
 |      otherwise throws an error.
 |
 |      See the docstring for ``get_submodule`` for a more detailed
 |      explanation of this method's functionality as well as how to
 |      correctly specify ``target``.
 |
 |      Args:
 |          target: The fully-qualified string name of the buffer
 |              to look for. (See ``get_submodule`` for how to specify a
 |              fully-qualified string.)
 |
 |      Returns:
 |          torch.Tensor: The buffer referenced by ``target``
 |
 |      Raises:
 |          AttributeError: If the target string references an invalid
 |              path or resolves to something that is not a
 |              buffer
 |
 |  get_parameter(self, target: str) -> 'Parameter'
 |      Returns the parameter given by ``target`` if it exists,
 |      otherwise throws an error.
 |
 |      See the docstring for ``get_submodule`` for a more detailed
 |      explanation of this method's functionality as well as how to
 |      correctly specify ``target``.
 |
 |      Args:
 |          target: The fully-qualified string name of the Parameter
 |              to look for. (See ``get_submodule`` for how to specify a
 |              fully-qualified string.)
 |
 |      Returns:
 |          torch.nn.Parameter: The Parameter referenced by ``target``
 |
 |      Raises:
 |          AttributeError: If the target string references an invalid
 |              path or resolves to something that is not an
 |              ``nn.Parameter``
 |
 |  get_submodule(self, target: str) -> 'Module'
 |      Returns the submodule given by ``target`` if it exists,
 |      otherwise throws an error.
 |
 |      For example, let's say you have an ``nn.Module`` ``A`` that
 |      looks like this:
 |
 |      .. code-block::text
 |
 |          A(
 |              (net_b): Module(
 |                  (net_c): Module(
 |                      (conv): Conv2d(16, 33, kernel_size=(3, 3), stride=(2, 2))
 |                  )
 |                  (linear): Linear(in_features=100, out_features=200, bias=True)
 |              )
 |          )
 |
 |      (The diagram shows an ``nn.Module`` ``A``. ``A`` has a nested
 |      submodule ``net_b``, which itself has two submodules ``net_c``
 |      and ``linear``. ``net_c`` then has a submodule ``conv``.)
 |
 |      To check whether or not we have the ``linear`` submodule, we
 |      would call ``get_submodule("net_b.linear")``. To check whether
 |      we have the ``conv`` submodule, we would call
 |      ``get_submodule("net_b.net_c.conv")``.
 |
 |      The runtime of ``get_submodule`` is bounded by the degree
 |      of module nesting in ``target``. A query against
 |      ``named_modules`` achieves the same result, but it is O(N) in
 |      the number of transitive modules. So, for a simple check to see
 |      if some submodule exists, ``get_submodule`` should always be
 |      used.
 |
 |      Args:
 |          target: The fully-qualified string name of the submodule
 |              to look for. (See above example for how to specify a
 |              fully-qualified string.)
 |
 |      Returns:
 |          torch.nn.Module: The submodule referenced by ``target``
 |
 |      Raises:
 |          AttributeError: If the target string references an invalid
 |              path or resolves to something that is not an
 |              ``nn.Module``
 |
 |  half(self: ~T) -> ~T
 |      Casts all floating point parameters and buffers to ``half`` datatype.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Returns:
 |          Module: self
 |
 |  load_state_dict(self, state_dict: 'OrderedDict[str, Tensor]', strict: bool = True)
 |      Copies parameters and buffers from :attr:`state_dict` into
 |      this module and its descendants. If :attr:`strict` is ``True``, then
 |      the keys of :attr:`state_dict` must exactly match the keys returned
 |      by this module's :meth:`~torch.nn.Module.state_dict` function.
 |
 |      Args:
 |          state_dict (dict): a dict containing parameters and
 |              persistent buffers.
 |          strict (bool, optional): whether to strictly enforce that the keys
 |              in :attr:`state_dict` match the keys returned by this module's
 |              :meth:`~torch.nn.Module.state_dict` function. Default: ``True``
 |
 |      Returns:
 |          ``NamedTuple`` with ``missing_keys`` and ``unexpected_keys`` fields:
 |              * **missing_keys** is a list of str containing the missing keys
 |              * **unexpected_keys** is a list of str containing the unexpected keys
 |
 |  modules(self) -> Iterator[ForwardRef('Module')]
 |      Returns an iterator over all modules in the network.
 |
 |      Yields:
 |          Module: a module in the network
 |
 |      Note:
 |          Duplicate modules are returned only once. In the following
 |          example, ``l`` will be returned only once.
 |
 |      Example::
 |
 |          >>> l = nn.Linear(2, 2)
 |          >>> net = nn.Sequential(l, l)
 |          >>> for idx, m in enumerate(net.modules()):
 |                  print(idx, '->', m)
 |
 |          0 -> Sequential(
 |            (0): Linear(in_features=2, out_features=2, bias=True)
 |            (1): Linear(in_features=2, out_features=2, bias=True)
 |          )
 |          1 -> Linear(in_features=2, out_features=2, bias=True)
 |
 |  named_buffers(self, prefix: str = '', recurse: bool = True) -> Iterator[Tuple[str, torch.Tensor]]
 |      Returns an iterator over module buffers, yielding both the
 |      name of the buffer as well as the buffer itself.
 |
 |      Args:
 |          prefix (str): prefix to prepend to all buffer names.
 |          recurse (bool): if True, then yields buffers of this module
 |              and all submodules. Otherwise, yields only buffers that
 |              are direct members of this module.
 |
 |      Yields:
 |          (string, torch.Tensor): Tuple containing the name and buffer
 |
 |      Example::
 |
 |          >>> for name, buf in self.named_buffers():
 |          >>>    if name in ['running_var']:
 |          >>>        print(buf.size())
 |
 |  named_children(self) -> Iterator[Tuple[str, ForwardRef('Module')]]
 |      Returns an iterator over immediate children modules, yielding both
 |      the name of the module as well as the module itself.
 |
 |      Yields:
 |          (string, Module): Tuple containing a name and child module
 |
 |      Example::
 |
 |          >>> for name, module in model.named_children():
 |          >>>     if name in ['conv4', 'conv5']:
 |          >>>         print(module)
 |
 |  named_modules(self, memo: Union[Set[ForwardRef('Module')], NoneType] = None, prefix: str = '', remove_duplicate: bool = True)
 |      Returns an iterator over all modules in the network, yielding
 |      both the name of the module as well as the module itself.
 |
 |      Args:
 |          memo: a memo to store the set of modules already added to the result
 |          prefix: a prefix that will be added to the name of the module
 |          remove_duplicate: whether to remove the duplicated module instances in the result
 |          or not
 |
 |      Yields:
 |          (string, Module): Tuple of name and module
 |
 |      Note:
 |          Duplicate modules are returned only once. In the following
 |          example, ``l`` will be returned only once.
 |
 |      Example::
 |
 |          >>> l = nn.Linear(2, 2)
 |          >>> net = nn.Sequential(l, l)
 |          >>> for idx, m in enumerate(net.named_modules()):
 |                  print(idx, '->', m)
 |
 |          0 -> ('', Sequential(
 |            (0): Linear(in_features=2, out_features=2, bias=True)
 |            (1): Linear(in_features=2, out_features=2, bias=True)
 |          ))
 |          1 -> ('0', Linear(in_features=2, out_features=2, bias=True))
 |
 |  named_parameters(self, prefix: str = '', recurse: bool = True) -> Iterator[Tuple[str, torch.nn.parameter.Parameter]]
 |      Returns an iterator over module parameters, yielding both the
 |      name of the parameter as well as the parameter itself.
 |
 |      Args:
 |          prefix (str): prefix to prepend to all parameter names.
 |          recurse (bool): if True, then yields parameters of this module
 |              and all submodules. Otherwise, yields only parameters that
 |              are direct members of this module.
 |
 |      Yields:
 |          (string, Parameter): Tuple containing the name and parameter
 |
 |      Example::
 |
 |          >>> for name, param in self.named_parameters():
 |          >>>    if name in ['bias']:
 |          >>>        print(param.size())
 |
 |  parameters(self, recurse: bool = True) -> Iterator[torch.nn.parameter.Parameter]
 |      Returns an iterator over module parameters.
 |
 |      This is typically passed to an optimizer.
 |
 |      Args:
 |          recurse (bool): if True, then yields parameters of this module
 |              and all submodules. Otherwise, yields only parameters that
 |              are direct members of this module.
 |
 |      Yields:
 |          Parameter: module parameter
 |
 |      Example::
 |
 |          >>> for param in model.parameters():
 |          >>>     print(type(param), param.size())
 |          <class 'torch.Tensor'> (20L,)
 |          <class 'torch.Tensor'> (20L, 1L, 5L, 5L)
 |
 |  register_backward_hook(self, hook: Callable[[ForwardRef('Module'), Union[Tuple[torch.Tensor, ...], torch.Tensor], Union[Tuple[torch.Tensor, ...], torch.Tensor]], Union[NoneType, torch.Tensor]]) -> torch.utils.hooks.RemovableHandle
 |      Registers a backward hook on the module.
 |
 |      This function is deprecated in favor of :meth:`nn.Module.register_full_backward_hook` and
 |      the behavior of this function will change in future versions.
 |
 |      Returns:
 |          :class:`torch.utils.hooks.RemovableHandle`:
 |              a handle that can be used to remove the added hook by calling
 |              ``handle.remove()``
 |
 |  register_buffer(self, name: str, tensor: Union[torch.Tensor, NoneType], persistent: bool = True) -> None
 |      Adds a buffer to the module.
 |
 |      This is typically used to register a buffer that should not to be
 |      considered a model parameter. For example, BatchNorm's ``running_mean``
 |      is not a parameter, but is part of the module's state. Buffers, by
 |      default, are persistent and will be saved alongside parameters. This
 |      behavior can be changed by setting :attr:`persistent` to ``False``. The
 |      only difference between a persistent buffer and a non-persistent buffer
 |      is that the latter will not be a part of this module's
 |      :attr:`state_dict`.
 |
 |      Buffers can be accessed as attributes using given names.
 |
 |      Args:
 |          name (string): name of the buffer. The buffer can be accessed
 |              from this module using the given name
 |          tensor (Tensor): buffer to be registered.
 |          persistent (bool): whether the buffer is part of this module's
 |              :attr:`state_dict`.
 |
 |      Example::
 |
 |          >>> self.register_buffer('running_mean', torch.zeros(num_features))
 |
 |  register_forward_hook(self, hook: Callable[..., NoneType]) -> torch.utils.hooks.RemovableHandle
 |      Registers a forward hook on the module.
 |
 |      The hook will be called every time after :func:`forward` has computed an output.
 |      It should have the following signature::
 |
 |          hook(module, input, output) -> None or modified output
 |
 |      The input contains only the positional arguments given to the module.
 |      Keyword arguments won't be passed to the hooks and only to the ``forward``.
 |      The hook can modify the output. It can modify the input inplace but
 |      it will not have effect on forward since this is called after
 |      :func:`forward` is called.
 |
 |      Returns:
 |          :class:`torch.utils.hooks.RemovableHandle`:
 |              a handle that can be used to remove the added hook by calling
 |              ``handle.remove()``
 |
 |  register_forward_pre_hook(self, hook: Callable[..., NoneType]) -> torch.utils.hooks.RemovableHandle
 |      Registers a forward pre-hook on the module.
 |
 |      The hook will be called every time before :func:`forward` is invoked.
 |      It should have the following signature::
 |
 |          hook(module, input) -> None or modified input
 |
 |      The input contains only the positional arguments given to the module.
 |      Keyword arguments won't be passed to the hooks and only to the ``forward``.
 |      The hook can modify the input. User can either return a tuple or a
 |      single modified value in the hook. We will wrap the value into a tuple
 |      if a single value is returned(unless that value is already a tuple).
 |
 |      Returns:
 |          :class:`torch.utils.hooks.RemovableHandle`:
 |              a handle that can be used to remove the added hook by calling
 |              ``handle.remove()``
 |
 |  register_full_backward_hook(self, hook: Callable[[ForwardRef('Module'), Union[Tuple[torch.Tensor, ...], torch.Tensor], Union[Tuple[torch.Tensor, ...], torch.Tensor]], Union[NoneType, torch.Tensor]]) -> torch.utils.hooks.RemovableHandle
 |      Registers a backward hook on the module.
 |
 |      The hook will be called every time the gradients with respect to module
 |      inputs are computed. The hook should have the following signature::
 |
 |          hook(module, grad_input, grad_output) -> tuple(Tensor) or None
 |
 |      The :attr:`grad_input` and :attr:`grad_output` are tuples that contain the gradients
 |      with respect to the inputs and outputs respectively. The hook should
 |      not modify its arguments, but it can optionally return a new gradient with
 |      respect to the input that will be used in place of :attr:`grad_input` in
 |      subsequent computations. :attr:`grad_input` will only correspond to the inputs given
 |      as positional arguments and all kwarg arguments are ignored. Entries
 |      in :attr:`grad_input` and :attr:`grad_output` will be ``None`` for all non-Tensor
 |      arguments.
 |
 |      .. warning ::
 |          Modifying inputs or outputs inplace is not allowed when using backward hooks and
 |          will raise an error.
 |
 |      Returns:
 |          :class:`torch.utils.hooks.RemovableHandle`:
 |              a handle that can be used to remove the added hook by calling
 |              ``handle.remove()``
 |
 |  register_parameter(self, name: str, param: Union[torch.nn.parameter.Parameter, NoneType]) -> None
 |      Adds a parameter to the module.
 |
 |      The parameter can be accessed as an attribute using given name.
 |
 |      Args:
 |          name (string): name of the parameter. The parameter can be accessed
 |              from this module using the given name
 |          param (Parameter): parameter to be added to the module.
 |
 |  requires_grad_(self: ~T, requires_grad: bool = True) -> ~T
 |      Change if autograd should record operations on parameters in this
 |      module.
 |
 |      This method sets the parameters' :attr:`requires_grad` attributes
 |      in-place.
 |
 |      This method is helpful for freezing part of the module for finetuning
 |      or training parts of a model individually (e.g., GAN training).
 |
 |      See :ref:`locally-disable-grad-doc` for a comparison between
 |      `.requires_grad_()` and several similar mechanisms that may be confused with it.
 |
 |      Args:
 |          requires_grad (bool): whether autograd should record operations on
 |                                parameters in this module. Default: ``True``.
 |
 |      Returns:
 |          Module: self
 |
 |  share_memory(self: ~T) -> ~T
 |      See :meth:`torch.Tensor.share_memory_`
 |
 |  state_dict(self, destination=None, prefix='', keep_vars=False)
 |      Returns a dictionary containing a whole state of the module.
 |
 |      Both parameters and persistent buffers (e.g. running averages) are
 |      included. Keys are corresponding parameter and buffer names.
 |
 |      Returns:
 |          dict:
 |              a dictionary containing a whole state of the module
 |
 |      Example::
 |
 |          >>> module.state_dict().keys()
 |          ['bias', 'weight']
 |
 |  to(self, *args, **kwargs)
 |      Moves and/or casts the parameters and buffers.
 |
 |      This can be called as
 |
 |      .. function:: to(device=None, dtype=None, non_blocking=False)
 |
 |      .. function:: to(dtype, non_blocking=False)
 |
 |      .. function:: to(tensor, non_blocking=False)
 |
 |      .. function:: to(memory_format=torch.channels_last)
 |
 |      Its signature is similar to :meth:`torch.Tensor.to`, but only accepts
 |      floating point or complex :attr:`dtype`s. In addition, this method will
 |      only cast the floating point or complex parameters and buffers to :attr:`dtype`
 |      (if given). The integral parameters and buffers will be moved
 |      :attr:`device`, if that is given, but with dtypes unchanged. When
 |      :attr:`non_blocking` is set, it tries to convert/move asynchronously
 |      with respect to the host if possible, e.g., moving CPU Tensors with
 |      pinned memory to CUDA devices.
 |
 |      See below for examples.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Args:
 |          device (:class:`torch.device`): the desired device of the parameters
 |              and buffers in this module
 |          dtype (:class:`torch.dtype`): the desired floating point or complex dtype of
 |              the parameters and buffers in this module
 |          tensor (torch.Tensor): Tensor whose dtype and device are the desired
 |              dtype and device for all parameters and buffers in this module
 |          memory_format (:class:`torch.memory_format`): the desired memory
 |              format for 4D parameters and buffers in this module (keyword
 |              only argument)
 |
 |      Returns:
 |          Module: self
 |
 |      Examples::
 |
 |          >>> linear = nn.Linear(2, 2)
 |          >>> linear.weight
 |          Parameter containing:
 |          tensor([[ 0.1913, -0.3420],
 |                  [-0.5113, -0.2325]])
 |          >>> linear.to(torch.double)
 |          Linear(in_features=2, out_features=2, bias=True)
 |          >>> linear.weight
 |          Parameter containing:
 |          tensor([[ 0.1913, -0.3420],
 |                  [-0.5113, -0.2325]], dtype=torch.float64)
 |          >>> gpu1 = torch.device("cuda:1")
 |          >>> linear.to(gpu1, dtype=torch.half, non_blocking=True)
 |          Linear(in_features=2, out_features=2, bias=True)
 |          >>> linear.weight
 |          Parameter containing:
 |          tensor([[ 0.1914, -0.3420],
 |                  [-0.5112, -0.2324]], dtype=torch.float16, device='cuda:1')
 |          >>> cpu = torch.device("cpu")
 |          >>> linear.to(cpu)
 |          Linear(in_features=2, out_features=2, bias=True)
 |          >>> linear.weight
 |          Parameter containing:
 |          tensor([[ 0.1914, -0.3420],
 |                  [-0.5112, -0.2324]], dtype=torch.float16)
 |
 |          >>> linear = nn.Linear(2, 2, bias=None).to(torch.cdouble)
 |          >>> linear.weight
 |          Parameter containing:
 |          tensor([[ 0.3741+0.j,  0.2382+0.j],
 |                  [ 0.5593+0.j, -0.4443+0.j]], dtype=torch.complex128)
 |          >>> linear(torch.ones(3, 2, dtype=torch.cdouble))
 |          tensor([[0.6122+0.j, 0.1150+0.j],
 |                  [0.6122+0.j, 0.1150+0.j],
 |                  [0.6122+0.j, 0.1150+0.j]], dtype=torch.complex128)
 |
 |  to_empty(self: ~T, *, device: Union[str, torch.device]) -> ~T
 |      Moves the parameters and buffers to the specified device without copying storage.
 |
 |      Args:
 |          device (:class:`torch.device`): The desired device of the parameters
 |              and buffers in this module.
 |
 |      Returns:
 |          Module: self
 |
 |  train(self: ~T, mode: bool = True) -> ~T
 |      Sets the module in training mode.
 |
 |      This has any effect only on certain modules. See documentations of
 |      particular modules for details of their behaviors in training/evaluation
 |      mode, if they are affected, e.g. :class:`Dropout`, :class:`BatchNorm`,
 |      etc.
 |
 |      Args:
 |          mode (bool): whether to set training mode (``True``) or evaluation
 |                       mode (``False``). Default: ``True``.
 |
 |      Returns:
 |          Module: self
 |
 |  type(self: ~T, dst_type: Union[torch.dtype, str]) -> ~T
 |      Casts all parameters and buffers to :attr:`dst_type`.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Args:
 |          dst_type (type or string): the desired type
 |
 |      Returns:
 |          Module: self
 |
 |  xpu(self: ~T, device: Union[int, torch.device, NoneType] = None) -> ~T
 |      Moves all model parameters and buffers to the XPU.
 |
 |      This also makes associated parameters and buffers different objects. So
 |      it should be called before constructing optimizer if the module will
 |      live on XPU while being optimized.
 |
 |      .. note::
 |          This method modifies the module in-place.
 |
 |      Arguments:
 |          device (int, optional): if specified, all parameters will be
 |              copied to that device
 |
 |      Returns:
 |          Module: self
 |
 |  zero_grad(self, set_to_none: bool = False) -> None
 |      Sets gradients of all model parameters to zero. See similar function
 |      under :class:`torch.optim.Optimizer` for more context.
 |
 |      Args:
 |          set_to_none (bool): instead of setting to zero, set the grads to None.
 |              See :meth:`torch.optim.Optimizer.zero_grad` for details.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from torch.nn.modules.module.Module:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from torch.nn.modules.module.Module:
 |
 |  T_destination = ~T_destination
 |
 |  dump_patches = False

</code>

## 5.5.1 LeNet模型 _____no_output_____

<code>
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(1, 6, 5), # in_channels, out_channels, kernel_size
            nn.Sigmoid(),
            nn.MaxPool2d(2, 2), # kernel_size, stride
            nn.Conv2d(6, 16, 5),
            nn.Sigmoid(),
            nn.MaxPool2d(2, 2)
        )
        self.fc = nn.Sequential(
            nn.Linear(16*4*4, 120),
            nn.Sigmoid(),
            nn.Linear(120, 84),
            nn.Sigmoid(),
            nn.Linear(84, 10)
        )

    def forward(self, img):
        feature = self.conv(img)
        output = self.fc(feature.view(img.shape[0], -1))
        return output_____no_output_____net = LeNet()
print(net)LeNet(
  (conv): Sequential(
    (0): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
    (1): Sigmoid()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
    (4): Sigmoid()
    (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (fc): Sequential(
    (0): Linear(in_features=256, out_features=120, bias=True)
    (1): Sigmoid()
    (2): Linear(in_features=120, out_features=84, bias=True)
    (3): Sigmoid()
    (4): Linear(in_features=84, out_features=10, bias=True)
  )
)

</code>

## 5.5.2 获取数据和训练模型_____no_output_____

<code>
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)_____no_output_____# 本函数已保存在d2lzh_pytorch包中方便以后使用。该函数将被逐步改进：它的完整实现将在“图像增广”一节中描述
def evaluate_accuracy(data_iter, net, device=None):
    if device is None and isinstance(net, torch.nn.Module):
        # 如果没指定device就使用net的device
        device = list(net.parameters())[0].device
    acc_sum, n = 0.0, 0
    with torch.no_grad():
        for X, y in data_iter:
            if isinstance(net, torch.nn.Module):
                net.eval() # 评估模式, 这会关闭dropout
                acc_sum += (net(X.to(device)).argmax(dim=1) == y.to(device)).float().sum().cpu().item()
                net.train() # 改回训练模式
            else: # 自定义的模型, 3.13节之后不会用到, 不考虑GPU
                if('is_training' in net.__code__.co_varnames): # 如果有is_training这个参数
                    # 将is_training设置成False
                    acc_sum += (net(X, is_training=False).argmax(dim=1) == y).float().sum().item()
                else:
                    acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
            n += y.shape[0]
    return acc_sum / n_____no_output_____# 本函数已保存在d2lzh_pytorch包中方便以后使用
def train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs):
    net = net.to(device)
    print("training on ", device)
    loss = torch.nn.CrossEntropyLoss()
    batch_count = 0
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n, start = 0.0, 0.0, 0, time.time()
        for X, y in train_iter:
            X = X.to(device)
            y = y.to(device)
            y_hat = net(X)
            l = loss(y_hat, y)
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
            train_l_sum += l.cpu().item()
            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().cpu().item()
            n += y.shape[0]
            batch_count += 1
        test_acc = evaluate_accuracy(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, time %.1f sec'
              % (epoch + 1, train_l_sum / batch_count, train_acc_sum / n, test_acc, time.time() - start))_____no_output_____lr, num_epochs = 0.001, 10
optimizer = torch.optim.Adam(net.parameters(), lr=lr)
train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)training on  cpu
epoch 1, loss 0.5509, train acc 0.783, test acc 0.785, time 10.7 sec
epoch 2, loss 0.2590, train acc 0.795, test acc 0.790, time 10.4 sec
epoch 3, loss 0.1649, train acc 0.802, test acc 0.804, time 10.9 sec
epoch 4, loss 0.1191, train acc 0.813, test acc 0.814, time 10.8 sec
epoch 5, loss 0.0920, train acc 0.822, test acc 0.819, time 11.0 sec
epoch 6, loss 0.0741, train acc 0.831, test acc 0.828, time 10.8 sec
epoch 7, loss 0.0615, train acc 0.837, test acc 0.833, time 11.1 sec
epoch 8, loss 0.0522, train acc 0.842, test acc 0.836, time 10.8 sec
epoch 9, loss 0.0453, train acc 0.848, test acc 0.843, time 11.0 sec
epoch 10, loss 0.0395, train acc 0.853, test acc 0.845, time 10.7 sec

</code>


# Notebook from Chibikuri/qiskit-tutorials
Path: community/awards/teach_me_quantum_2018/bronze/bronze/B04_hello_from_quantum_world.ipynb

	prepared by Abuzer Yakaryilmaz (QuSoft@Riga) | November 02, 2018

 I have some macros here. If there is a problem with displaying mathematical formulas, please run me to load these macros.

$ \newcommand{\bra}[1]{\langle #1|} $
$ \newcommand{\ket}[1]{|#1\rangle} $
$ \newcommand{\braket}[2]{\langle #1|#2\rangle} $
$ \newcommand{\inner}[2]{\langle #1,#2\rangle} $
$ \newcommand{\biginner}[2]{\left\langle #1,#2\right\rangle} $
$ \newcommand{\mymatrix}[2]{\left( \begin{array}{#1} #2\end{array} \right)} $
$ \newcommand{\myvector}[1]{\mymatrix{c}{#1}} $
$ \newcommand{\myrvector}[1]{\mymatrix{r}{#1}} $
$ \newcommand{\mypar}[1]{\left( #1 \right)} $
$ \newcommand{\mybigpar}[1]{ \Big( #1 \Big)} $
$ \newcommand{\sqrttwo}{\frac{1}{\sqrt{2}}} $
$ \newcommand{\dsqrttwo}{\dfrac{1}{\sqrt{2}}} $
$ \newcommand{\onehalf}{\frac{1}{2}} $
$ \newcommand{\donehalf}{\dfrac{1}{2}} $
$ \newcommand{\hadamard}{ \mymatrix{rr}{ \sqrttwo & \sqrttwo \\ \sqrttwo & -\sqrttwo }} $
$ \newcommand{\vzero}{\myvector{1\\0}} $
$ \newcommand{\vone}{\myvector{0\\1}} $
$ \newcommand{\vhadamardzero}{\myvector{ \sqrttwo \\  \sqrttwo } } $
$ \newcommand{\vhadamardone}{ \myrvector{ \sqrttwo \\ -\sqrttwo } } $
$ \newcommand{\myarray}[2]{ \begin{array}{#1}#2\end{array}} $
$ \newcommand{\X}{ \mymatrix{cc}{0 & 1 \\ 1 & 0}  } $
$ \newcommand{\Z}{ \mymatrix{rr}{1 & 0 \\ 0 & -1}  } $
$ \newcommand{\Htwo}{ \mymatrix{rrrr}{ \frac{1}{2} & \frac{1}{2} & \frac{1}{2} & \frac{1}{2} \\ \frac{1}{2} & -\frac{1}{2} & \frac{1}{2} & -\frac{1}{2} \\ \frac{1}{2} & \frac{1}{2} & -\frac{1}{2} & -\frac{1}{2} \\ \frac{1}{2} & -\frac{1}{2} & -\frac{1}{2} & \frac{1}{2} } } $
$ \newcommand{\CNOT}{ \mymatrix{cccc}{1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0} } $
$ \newcommand{\norm}[1]{ \left\lVert #1 \right\rVert } $_____no_output_____
 Hello From Quantum World

This is our test file.

Please run each cell one by one._____no_output_____
 Sqaure brackets on the left sides of the code cells

 Each pair of the brackets shows the execution counter of the cell.

 If the cell has not been executed, the inside of the brackets is empty.

 When the code cell is still running, there appears a single star inside the brackets [*].

 When the execution is finished, there appears a number inside the brackets [number].

 A cell can be executed many times. Each time it takes a new number (in increasing order).

The execution of a cell may take a few miliseconds, a few seconds, a few minutes, or much longer time.

 Therefore, you may not see any outcome until [*] is changed to [number]._____no_output_____
 Python Test
_____no_output_____

# I am a comment in python

print("Hello From Quantum World :-)")

# please run me_____no_output_____

 Quantum Circuit Test

Our quantum programs are designed as quantum curcits.

Explanations will appear in the main tutorial.

We create a very simple quantum circuit

Please run the cell below, and wait until the execution is completed.

Remark that we call a function or an object from a module in python as

from module-name import function-name

from module-name import object-name
_____no_output_____

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer
from random import randrange

# Create my circuit and register objects
qreg = QuantumRegister(2) # my quantum register
creg = ClassicalRegister(2) # my classical register
circuit = QuantumCircuit(qreg,creg) # my quantum circuit

# let's apply a Hadamard gate to the first qubit

circuit.h(qreg[0])

# let's set the second qubit to |1>
circuit.x(qreg[1])

# let's apply CNOT(first_qubit,second_qubit)
circuit.cx(qreg[0],qreg[1])

# let's measure the both qubits
circuit.measure(qreg,creg)

print("The execution was completed, and the circuit was created :)")_____no_output_____

We execute the circuit (our program) 1024 times in the local simulator

Each execution may have a different outcome (?).

In our simple program, we expect to observe either 01 or 10 as the outcome in a single execution.

We print the measurement results.

Thus, we will see how many times '01' is observed and how many times '10' is observed.

You may execute this cell a few times, and check the outcomes in each case._____no_output_____

## execute the circuit 100 times
job = execute(circuit,Aer.get_backend('qasm_simulator'),shots=1024)
# get the result
counts = job.result().get_counts(circuit)
print(counts)_____no_output_____

Draw the circuit

We can draw our circuit.

If the circuit does not appear in the first run, please re-run the cell._____no_output_____

from qiskit.tools.visualization import matplotlib_circuit_drawer as drawer
# draw the overall circuit
drawer(circuit)
# re-execute me if you DO NOT see the circuit diagram_____no_output_____

IBMQ Test

 The remaining part requires internet connection.

We will execute our test circuit on IBM simulator, and then on one of IBM real qauntum computers.

 Please wait the execution of each cell to be completed, before executing the next cell._____no_output_____
 Save your API on the disk

Please write YOUR IBM API TOKEN in the following cell, and then run the cell.

(The instruction is given at the end of section "Testing: First Program" in the file bronze-start.html

Once your YOUR IBM API TOKEN is saved on the disk,  it can be directly used later._____no_output_____

from qiskit import IBMQ

IBMQ.save_account('write YOUR IBM API TOKEN here')

# Then, execute this cell_____no_output_____

 See the stored account(s)
_____no_output_____

IBMQ.stored_accounts()_____no_output_____

 Load our account(s)
_____no_output_____

IBMQ.load_accounts()_____no_output_____

 See the active account(s)
_____no_output_____

IBMQ.active_accounts()_____no_output_____

See available backends
_____no_output_____

IBMQ.backends()_____no_output_____

 See the currently operational real quantum computer(s)
_____no_output_____

IBMQ.backends(operational=True, simulator=False)_____no_output_____

 See the least busy real quantum computer
 _____no_output_____

from qiskit.backends.ibmq import least_busy
least_busy(IBMQ.backends(simulator=False))_____no_output_____

 IBMQ simulator
_____no_output_____
 Use the simulator as backend
_____no_output_____

backend = least_busy(IBMQ.backends(simulator=True))

backend.name()_____no_output_____

 Create a job for the backend
_____no_output_____

from qiskit import compile

qobj = compile(circuit, backend=backend, shots=1024)_____no_output_____

 Execute this job on the simulator
_____no_output_____

job = backend.run(qobj)_____no_output_____

 Check the result
_____no_output_____

result = job.result()
counts = result.get_counts()
print(counts)_____no_output_____

 IBMQ real quantum computers (Optional)

Please read the following  part to see IBM's policy for usage for the prototype real quantum computers. [accessed on October 28, 2018]

    Frequently Asked Questions

https://quantumexperience.ng.bluemix.net/proxy/tutorial/full-user-guide/000-FAQ/000-Frequently_Asked_Questions.html

How many experiments can I run?

You can run as many experiments as you have Units to run; each experiment execution requires between 3 and 5 Units. No Units are required to perform simulations or to recall results of an experiment that was run previously.

What happens when I run out of Units?

You can still run simulations or recall the result of the experiments that have been run previously, but you must wait for the Units to replenish, which happens either once your execution has run off the queue, or 24 hours, whichever is greater.

You can check your Units in your IBM Q Experience account (My Account > Advanced). _____no_output_____
 Use the least busy real machine as backend
_____no_output_____

backend_real = least_busy(IBMQ.backends(simulator=False))

backend_real.name()

backend_real.status()_____no_output_____

 Execute the same job on a real machine

Depending on the number of pending jobs, it might take for a while to execute our job on the real machine.

 If you do not have enough Units, you should wait for 24 hours to execute your quantum program on a real machine.

 But, this would not be a problem to complete Bronze, because we use the local simulator for our tasks. _____no_output_____

qobj_real = compile(circuit, backend=backend_real, shots=1024)

job_real = backend_real.run(qobj_real)

job_real.queue_position()_____no_output_____

 Check the result
_____no_output_____

result_real = job_real.result()
counts_real = result_real.get_counts()
print(counts_real)_____no_output_____

 You may finish this notebook before getting the outcomes, if it seems to take long time.

You may observe more than two outcomes, different than the simulators.

The expected outcomes '01' and '10' can still be observed more frequently, but we may also observe the unexpected outcomes '00' and '11'. Because, even after a single operation, the prototype quantum computers introduce some errors._____no_output_____