Esempio n. 1
0
def create_analog_network(input_size, hidden_sizes, output_size):
    """Create the neural network using analog and digital layers.

    Args:
        input_size (int): size of the Tensor at the input.
        hidden_sizes (list): list of sizes of the hidden layers (2 layers).
        output_size (int): size of the Tensor at the output.
    """
    model = nn.Sequential(
        AnalogLinear(input_size,
                     hidden_sizes[0],
                     True,
                     resistive_device=ConstantStepResistiveDevice()),
        nn.Sigmoid(),
        AnalogLinear(hidden_sizes[0],
                     hidden_sizes[1],
                     True,
                     resistive_device=ConstantStepResistiveDevice()),
        nn.Sigmoid(),
        AnalogLinear(hidden_sizes[1],
                     output_size,
                     True,
                     resistive_device=ConstantStepResistiveDevice()),
        nn.LogSoftmax(dim=1))
    print(model)
    return model
Esempio n. 2
0
 def get_layer(self, cols, rows):
     """Return a layer."""
     return AnalogLinear(
         cols,
         rows,
         bias=True,
         resistive_device=ConstantStepResistiveDevice()).cuda()
Esempio n. 3
0
    def test_save_load_meta_parameter(self):
        """Test saving and loading a device with custom parameters."""
        params_devices = ConstantStepResistiveDeviceParameters(w_max=0.987)
        params_forward = AnalogTileInputOutputParameters(inp_noise=0.321)
        params_backward = AnalogTileBackwardInputOutputParameters(
            inp_noise=0.456)
        params_update = AnalogTileUpdateParameters(desired_bl=78)

        # Create the device and the array.
        resistive_device = ConstantStepResistiveDevice(params_devices,
                                                       params_forward,
                                                       params_backward,
                                                       params_update)

        model = self.get_model(resistive_device=resistive_device)

        # Save the model to a file.
        file = TemporaryFile()
        save(model, file)

        # Load the model.
        file.seek(0)
        new_model = load(file)
        file.close()

        # Assert over the new model tile parameters.
        parameters = new_model.analog_tile.tile.get_parameters()
        self.assertAlmostEqual(parameters.forward_io.inp_noise, 0.321)
        self.assertAlmostEqual(parameters.backward_io.inp_noise, 0.456)
        self.assertAlmostEqual(parameters.update.desired_bl, 78)
Esempio n. 4
0
 def get_tile(self, out_size, in_size, device_params=None):
     """Return an analog tile of the specified dimensions."""
     device_params = device_params or ConstantStepResistiveDeviceParameters(
     )
     resistive_device = ConstantStepResistiveDevice(
         params_devices=device_params)
     python_tile = AnalogTile(out_size, in_size, resistive_device)
     self.set_init_weights(python_tile)
     return python_tile
Esempio n. 5
0
 def get_layer(self, cols=3, rows=4, **kwargs):
     """Return a layer."""
     # pylint: disable=arguments-differ
     return AnalogLinear(cols,
                         rows,
                         resistive_device=ConstantStepResistiveDevice(
                             ConstantStepResistiveDeviceParameters(
                                 w_max_dtod=0, w_min_dtod=0)),
                         **kwargs).cuda()
Esempio n. 6
0
 def get_model(self, **kwargs):
     """Return a layer."""
     if 'resistive_device' not in kwargs:
         kwargs['resistive_device'] = ConstantStepResistiveDevice()
     return AnalogConv2d(in_channels=2,
                         out_channels=3,
                         kernel_size=4,
                         padding=2,
                         **kwargs).cuda()
Esempio n. 7
0
    def test_device_parameter_constructor(self):
        """Test creating a device using parameters in the constructor."""
        params_devices = ConstantStepResistiveDeviceParameters(w_max=0.987)
        params_forward = AnalogTileInputOutputParameters(inp_noise=0.321)
        params_backward = AnalogTileBackwardInputOutputParameters(
            inp_noise=0.456)
        params_update = AnalogTileUpdateParameters(desired_bl=78)

        # Create the device and the array.
        resistive_device = ConstantStepResistiveDevice(params_devices,
                                                       params_forward,
                                                       params_backward,
                                                       params_update)
        analog_tile = resistive_device.create_tile(10, 20)

        # Assert over the parameters in the binding objects.
        parameters = analog_tile.get_parameters()
        self.assertAlmostEqual(parameters.forward_io.inp_noise, 0.321)
        self.assertAlmostEqual(parameters.backward_io.inp_noise, 0.456)
        self.assertAlmostEqual(parameters.update.desired_bl, 78)
Esempio n. 8
0
    def _setup_tile(self,
                    in_features: int,
                    out_features: int,
                    bias: bool,
                    resistive_device: Optional[BaseResistiveDevice] = None,
                    realistic_read_write: bool = False) -> BaseTile:
        """Create an analog tile and setup this layer for using it.

        Create an analog tile to be used for the basis of this layer operations,
        and setup additional attributes of this instance that are needed for
        using the analog tile.

        Note:
            This method also sets the following attributes, which are assumed
            to be set by the rest of the methods:
            * ``self.use_bias``
            * ``self.realistic_read_write``
            * ``self.in_features``
            * ``self.out_features``

        Args:
            in_features: input vector size (number of columns).
            out_features: output vector size (number of rows).
            resistive_device: analog devices that define the properties of the
                analog tile.
            bias: whether to use a bias row on the analog tile or not.
            realistic_read_write: whether to enable realistic read/write
               for setting initial weights and read out of weights.
        """
        # pylint: disable=attribute-defined-outside-init
        # Default to constant step device if not provided.
        if not resistive_device:
            resistive_device = ConstantStepResistiveDevice()

        # Setup the analog-related attributes of this instance.
        self.use_bias = bias
        self.realistic_read_write = realistic_read_write
        self.in_features = in_features
        self.out_features = out_features

        # Create the tile.
        if isinstance(resistive_device, FloatingPointResistiveDevice):
            tile_class = self.TILE_CLASS_FLOATING_POINT
        else:
            tile_class = self.TILE_CLASS_ANALOG  # type: ignore

        return tile_class(
            out_features,
            in_features,
            resistive_device,
            bias=bias  # type: ignore
        )
Esempio n. 9
0
 def __init__(
     self,
     out_size: int,
     in_size: int,
     resistive_device: Optional[BaseResistiveDevice] = None,
     bias: bool = False,
     in_trans: bool = False,
     out_trans: bool = False,
 ):
     self.resistive_device = resistive_device or ConstantStepResistiveDevice(
     )
     super().__init__(out_size, in_size, self.resistive_device, bias,
                      in_trans, out_trans)
Esempio n. 10
0
 def get_layer(self,
               in_channels=2,
               out_channels=3,
               kernel_size=4,
               **kwargs):
     """Return a layer."""
     # pylint: disable=arguments-differ
     return AnalogConv2d(in_channels,
                         out_channels,
                         kernel_size,
                         resistive_device=ConstantStepResistiveDevice(
                             ConstantStepResistiveDeviceParameters(
                                 w_max_dtod=0, w_min_dtod=0)),
                         **kwargs).cuda()
    def get_tile(self, out_size, in_size):
        """Return a tile of the specified dimensions with noisiness turned off."""
        params = ConstantStepResistiveDeviceParameters()
        io_params = AnalogTileInputOutputParameters(is_perfect=True)
        io_params_backward = AnalogTileBackwardInputOutputParameters(
            is_perfect=True)
        up_params = AnalogTileUpdateParameters(pulse_type=PulseType('None'))
        resistive_device = ConstantStepResistiveDevice(
            params_devices=params,
            params_forward=io_params,
            params_backward=io_params_backward,
            params_update=up_params)
        python_tile = NumpyAnalogTile(out_size, in_size, resistive_device)

        # Set weights.
        init_weights = uniform(-0.5,
                               0.5,
                               size=(python_tile.out_size,
                                     python_tile.in_size))
        python_tile.set_weights(from_numpy(init_weights))

        return python_tile
Esempio n. 12
0
    def test_constant_step_device_array(self):
        """Test creating an array from a `ConstantStepResistiveDevice`."""
        resistive_device = ConstantStepResistiveDevice()
        analog_tile = resistive_device.create_tile(2, 4)

        self.assertIsInstance(analog_tile, AnalogTile)
Esempio n. 13
0
from torch import Tensor
from torch.nn.functional import mse_loss
from torch.nn import Sequential

# Imports from aihwkit.
from aihwkit.nn import AnalogLinear
from aihwkit.optim.analog_sgd import AnalogSGD
from aihwkit.simulator.devices import ConstantStepResistiveDevice

# Prepare the datasets (input and expected output).
x_b = Tensor([[0.1, 0.2, 0.0, 0.0], [0.2, 0.4, 0.0, 0.0]])
y_b = Tensor([[0.3], [0.6]])

# Define a multiple-layer network, using a constant step device type.
model = Sequential(
    AnalogLinear(4, 2, resistive_device=ConstantStepResistiveDevice()),
    AnalogLinear(2, 2, resistive_device=ConstantStepResistiveDevice()),
    AnalogLinear(2, 1, resistive_device=ConstantStepResistiveDevice()))

# Define an analog-aware optimizer, preparing it for using the layers.
opt = AnalogSGD(model.parameters(), lr=0.5)
opt.regroup_param_groups(model)

for epoch in range(100):
    # Add the training Tensor to the model (input).
    pred = model(x_b)
    # Add the expected output Tensor.
    loss = mse_loss(pred, y_b)
    # Run training (backward propagation).
    loss.backward()
Esempio n. 14
0
    def get_tile(self, out_size, in_size, **kwargs):
        resistive_device = ConstantStepResistiveDevice(
            ConstantStepResistiveDeviceParameters(w_max_dtod=0, w_min_dtod=0))

        return AnalogTile(out_size, in_size, resistive_device, **kwargs).cuda()
Esempio n. 15
0
# Imports from PyTorch.
from torch import Tensor
from torch.nn.functional import mse_loss

# Imports from aihwkit.
from aihwkit.nn import AnalogLinear
from aihwkit.optim.analog_sgd import AnalogSGD
from aihwkit.simulator.devices import ConstantStepResistiveDevice
from aihwkit.simulator.rpu_base import cuda

# Prepare the datasets (input and expected output).
x = Tensor([[0.1, 0.2, 0.4, 0.3], [0.2, 0.1, 0.1, 0.3]])
y = Tensor([[1.0, 0.5], [0.7, 0.3]])

# Define a single-layer network, using a constant step device type.
analog_device = ConstantStepResistiveDevice()
model = AnalogLinear(4, 2, bias=True, resistive_device=analog_device)

# Move the model and tensors to cuda if it is available.
if cuda.is_compiled():
    x = x.cuda()
    y = y.cuda()
    model.cuda()

# Define an analog-aware optimizer, preparing it for using the layers.
opt = AnalogSGD(model.parameters(), lr=0.1)
opt.regroup_param_groups(model)

for epoch in range(100):
    # Add the training Tensor to the model (input).
    pred = model(x)
Esempio n. 16
0
 def get_model(self, **kwargs):
     """Return a layer."""
     if 'resistive_device' not in kwargs:
         kwargs['resistive_device'] = ConstantStepResistiveDevice()
     return AnalogLinear(in_features=5, out_features=3, **kwargs).cuda()