




'''simple docstring'''

from dataclasses import dataclass
from typing import Optional

import numpy as np
import torch
import torch.nn as nn

from ..utils import BaseOutput, is_torch_version, randn_tensor
from .attention_processor import SpatialNorm
from .unet_ad_blocks import UNetMidBlockaD, get_down_block, get_up_block

@dataclass
class __snake_case(				_lowerCAmelCase ):


						'''simple docstring'''



						UpperCAmelCase							:   torch.FloatTensor







class __snake_case(				nn.Module ):


						'''simple docstring'''



						def __init__( self     ,	A_=3     ,	A_=3     ,	A_=("DownEncoderBlock2D",)     ,	A_=(64,)     ,	A_=2     ,	A_=32     ,	A_="silu"     ,	A_=True     ,	)     ->     int:
							super().__init__()
							lowerCAmelCase   =     layers_per_block

							lowerCAmelCase   =     torch.nn.Convad(
							    A_     ,	block_out_channels[0]     ,	kernel_size=3     ,	stride=1     ,	padding=1     ,	)

							lowerCAmelCase   =     None
							lowerCAmelCase   =     nn.ModuleList([]				)

							# down
							lowerCAmelCase   =     block_out_channels[0]
							for i, down_block_type in enumerate(A_				):
								lowerCAmelCase   =     output_channel
								lowerCAmelCase   =     block_out_channels[i]
								lowerCAmelCase   =     i == len(A_				) - 1

								lowerCAmelCase   =     get_down_block(
								    A_     ,	num_layers=self.layers_per_block     ,	in_channels=A_     ,	out_channels=A_     ,	add_downsample=not is_final_block     ,	resnet_eps=1e-6     ,	downsample_padding=0     ,	resnet_act_fn=A_     ,	resnet_groups=A_     ,	attention_head_dim=A_     ,	temb_channels=A_     ,	)
								self.down_blocks.append(A_				)

							# mid
							lowerCAmelCase   =     UNetMidBlockaD(
							    in_channels=block_out_channels[-1]     ,	resnet_eps=1e-6     ,	resnet_act_fn=A_     ,	output_scale_factor=1     ,	resnet_time_scale_shift="""default"""     ,	attention_head_dim=block_out_channels[-1]     ,	resnet_groups=A_     ,	temb_channels=A_     ,	)

							# out
							lowerCAmelCase   =     nn.GroupNorm(num_channels=block_out_channels[-1]     ,	num_groups=A_     ,	eps=1e-6				)
							lowerCAmelCase   =     nn.SiLU()

							lowerCAmelCase   =     2 * out_channels if double_z else out_channels
							lowerCAmelCase   =     nn.Convad(block_out_channels[-1]     ,	A_     ,	3     ,	padding=1				)

							lowerCAmelCase   =     False




						def     __snake_case   ( self     ,	A_				)     ->     List[str]:
							lowerCAmelCase   =     x
							lowerCAmelCase   =     self.conv_in(A_				)

							if self.training and self.gradient_checkpointing:

								def create_custom_forward(A_				):
									def custom_forward(*A_				):
										return module(*A_				)

									return custom_forward

								# down
								if is_torch_version(""">="""     ,	"""1.11.0"""				):
									for down_block in self.down_blocks:
										lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(
										    create_custom_forward(A_				)     ,	A_     ,	use_reentrant=A_				)
									# middle
									lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(
									    create_custom_forward(self.mid_block				)     ,	A_     ,	use_reentrant=A_				)
								else:
									for down_block in self.down_blocks:
										lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(create_custom_forward(A_				)     ,	A_				)
									# middle
									lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(create_custom_forward(self.mid_block				)     ,	A_				)

							else:
								# down
								for down_block in self.down_blocks:
									lowerCAmelCase   =     down_block(A_				)

								# middle
								lowerCAmelCase   =     self.mid_block(A_				)

							# post-process
							lowerCAmelCase   =     self.conv_norm_out(A_				)
							lowerCAmelCase   =     self.conv_act(A_				)
							lowerCAmelCase   =     self.conv_out(A_				)

							return sample







class __snake_case(				nn.Module ):


						'''simple docstring'''



						def __init__( self     ,	A_=3     ,	A_=3     ,	A_=("UpDecoderBlock2D",)     ,	A_=(64,)     ,	A_=2     ,	A_=32     ,	A_="silu"     ,	A_="group"     ,	)     ->     Tuple:
							super().__init__()
							lowerCAmelCase   =     layers_per_block

							lowerCAmelCase   =     nn.Convad(
							    A_     ,	block_out_channels[-1]     ,	kernel_size=3     ,	stride=1     ,	padding=1     ,	)

							lowerCAmelCase   =     None
							lowerCAmelCase   =     nn.ModuleList([]				)

							lowerCAmelCase   =     in_channels if norm_type == """spatial""" else None

							# mid
							lowerCAmelCase   =     UNetMidBlockaD(
							    in_channels=block_out_channels[-1]     ,	resnet_eps=1e-6     ,	resnet_act_fn=A_     ,	output_scale_factor=1     ,	resnet_time_scale_shift="""default""" if norm_type == """group""" else norm_type     ,	attention_head_dim=block_out_channels[-1]     ,	resnet_groups=A_     ,	temb_channels=A_     ,	)

							# up
							lowerCAmelCase   =     list(reversed(A_				)				)
							lowerCAmelCase   =     reversed_block_out_channels[0]
							for i, up_block_type in enumerate(A_				):
								lowerCAmelCase   =     output_channel
								lowerCAmelCase   =     reversed_block_out_channels[i]

								lowerCAmelCase   =     i == len(A_				) - 1

								lowerCAmelCase   =     get_up_block(
								    A_     ,	num_layers=self.layers_per_block + 1     ,	in_channels=A_     ,	out_channels=A_     ,	prev_output_channel=A_     ,	add_upsample=not is_final_block     ,	resnet_eps=1e-6     ,	resnet_act_fn=A_     ,	resnet_groups=A_     ,	attention_head_dim=A_     ,	temb_channels=A_     ,	resnet_time_scale_shift=A_     ,	)
								self.up_blocks.append(A_				)
								lowerCAmelCase   =     output_channel

							# out
							if norm_type == "spatial":
								lowerCAmelCase   =     SpatialNorm(block_out_channels[0]     ,	A_				)
							else:
								lowerCAmelCase   =     nn.GroupNorm(num_channels=block_out_channels[0]     ,	num_groups=A_     ,	eps=1e-6				)
							lowerCAmelCase   =     nn.SiLU()
							lowerCAmelCase   =     nn.Convad(block_out_channels[0]     ,	A_     ,	3     ,	padding=1				)

							lowerCAmelCase   =     False




						def     __snake_case   ( self     ,	A_     ,	A_=None				)     ->     Any:
							lowerCAmelCase   =     z
							lowerCAmelCase   =     self.conv_in(A_				)

							lowerCAmelCase   =     next(iter(self.up_blocks.parameters()				)				).dtype
							if self.training and self.gradient_checkpointing:

								def create_custom_forward(A_				):
									def custom_forward(*A_				):
										return module(*A_				)

									return custom_forward

								if is_torch_version(""">="""     ,	"""1.11.0"""				):
									# middle
									lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(
									    create_custom_forward(self.mid_block				)     ,	A_     ,	A_     ,	use_reentrant=A_				)
									lowerCAmelCase   =     sample.to(A_				)

									# up
									for up_block in self.up_blocks:
										lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(
										    create_custom_forward(A_				)     ,	A_     ,	A_     ,	use_reentrant=A_				)
								else:
									# middle
									lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(
									    create_custom_forward(self.mid_block				)     ,	A_     ,	A_				)
									lowerCAmelCase   =     sample.to(A_				)

									# up
									for up_block in self.up_blocks:
										lowerCAmelCase   =     torch.utils.checkpoint.checkpoint(create_custom_forward(A_				)     ,	A_     ,	A_				)
							else:
								# middle
								lowerCAmelCase   =     self.mid_block(A_     ,	A_				)
								lowerCAmelCase   =     sample.to(A_				)

								# up
								for up_block in self.up_blocks:
									lowerCAmelCase   =     up_block(A_     ,	A_				)

        # post-process
							if latent_embeds is None:
								lowerCAmelCase   =     self.conv_norm_out(A_				)
							else:
								lowerCAmelCase   =     self.conv_norm_out(A_     ,	A_				)
							lowerCAmelCase   =     self.conv_act(A_				)
							lowerCAmelCase   =     self.conv_out(A_				)

							return sample







class __snake_case(				nn.Module ):


						'''simple docstring'''



						def __init__( self     ,	A_     ,	A_     ,	A_     ,	A_=None     ,	A_="random"     ,	A_=False     ,	A_=True				)     ->     int:
							super().__init__()
							lowerCAmelCase   =     n_e
							lowerCAmelCase   =     vq_embed_dim
							lowerCAmelCase   =     beta
							lowerCAmelCase   =     legacy

							lowerCAmelCase   =     nn.Embedding(self.n_e     ,	self.vq_embed_dim				)
							self.embedding.weight.data.uniform_(-1.0 / self.n_e     ,	1.0 / self.n_e				)

							lowerCAmelCase   =     remap
							if self.remap is not None:
								self.register_buffer("""used"""     ,	torch.tensor(np.load(self.remap				)				)				)
								lowerCAmelCase   =     self.used.shape[0]
								lowerCAmelCase   =     unknown_index  # "random" or "extra" or integer
								if self.unknown_index == "extra":
									lowerCAmelCase   =     self.re_embed
									lowerCAmelCase   =     self.re_embed + 1
								print(
								    f'Remapping {self.n_e} indices to {self.re_embed} indices. '
								    f'Using {self.unknown_index} for unknown indices.'				)
							else:
								lowerCAmelCase   =     n_e

							lowerCAmelCase   =     sane_index_shape


						def     __snake_case   ( self     ,	A_				)     ->     Dict:
							lowerCAmelCase   =     inds.shape
							assert len(A_				) > 1
							lowerCAmelCase   =     inds.reshape(ishape[0]     ,	-1				)
							lowerCAmelCase   =     self.used.to(A_				)
							lowerCAmelCase   =     (inds[:, :, None] == used[None, None, ...]).long()
							lowerCAmelCase   =     match.argmax(-1				)
							lowerCAmelCase   =     match.sum(2				) < 1
							if self.unknown_index == "random":
								lowerCAmelCase   =     torch.randint(0     ,	self.re_embed     ,	size=new[unknown].shape				).to(device=new.device				)
							else:
								lowerCAmelCase   =     self.unknown_index
							return new.reshape(A_				)


						def     __snake_case   ( self     ,	A_				)     ->     List[Any]:
							lowerCAmelCase   =     inds.shape
							assert len(A_				) > 1
							lowerCAmelCase   =     inds.reshape(ishape[0]     ,	-1				)
							lowerCAmelCase   =     self.used.to(A_				)
							if self.re_embed > self.used.shape[0]:  # extra token
								lowerCAmelCase   =     0  # simply set to zero
							lowerCAmelCase   =     torch.gather(used[None, :][inds.shape[0] * [0], :]     ,	1     ,	A_				)
							return back.reshape(A_				)


						def     __snake_case   ( self     ,	A_				)     ->     Union[str, Any]:
							# reshape z -> (batch, height, width, channel) and flatten
							lowerCAmelCase   =     z.permute(0     ,	2     ,	3     ,	1				).contiguous()
							lowerCAmelCase   =     z.view(-1     ,	self.vq_embed_dim				)

							# distances from z to embeddings e_j (z - e)^2 = z^2 + e^2 - 2 e * z
							lowerCAmelCase   =     torch.argmin(torch.cdist(A_     ,	self.embedding.weight				)     ,	dim=1				)

							lowerCAmelCase   =     self.embedding(A_				).view(z.shape				)
							lowerCAmelCase   =     None
							lowerCAmelCase   =     None

							# compute loss for embedding
							if not self.legacy:
								lowerCAmelCase   =     self.beta * torch.mean((z_q.detach() - z) ** 2				) + torch.mean((z_q - z.detach()) ** 2				)
							else:
								lowerCAmelCase   =     torch.mean((z_q.detach() - z) ** 2				) + self.beta * torch.mean((z_q - z.detach()) ** 2				)

							# preserve gradients
							lowerCAmelCase   =     z + (z_q - z).detach()

							# reshape back to match original input shape
							lowerCAmelCase   =     z_q.permute(0     ,	3     ,	1     ,	2				).contiguous()

							if self.remap is not None:
								lowerCAmelCase   =     min_encoding_indices.reshape(z.shape[0]     ,	-1				)  # add batch axis
								lowerCAmelCase   =     self.remap_to_used(A_				)
								lowerCAmelCase   =     min_encoding_indices.reshape(-1     ,	1				)  # flatten

							if self.sane_index_shape:
								lowerCAmelCase   =     min_encoding_indices.reshape(z_q.shape[0]     ,	z_q.shape[2]     ,	z_q.shape[3]				)

							return z_q, loss, (perplexity, min_encodings, min_encoding_indices)




						def     __snake_case   ( self     ,	A_     ,	A_				)     ->     List[str]:
							# shape specifying (batch, height, width, channel)
							if self.remap is not None:
								lowerCAmelCase   =     indices.reshape(shape[0]     ,	-1				)  # add batch axis
								lowerCAmelCase   =     self.unmap_to_all(A_				)
								lowerCAmelCase   =     indices.reshape(-1				)  # flatten again

							# get quantized latent vectors
							lowerCAmelCase   =     self.embedding(A_				)

							if shape is not None:
								lowerCAmelCase   =     z_q.view(A_				)
								# reshape back to match original input shape
								lowerCAmelCase   =     z_q.permute(0     ,	3     ,	1     ,	2				).contiguous()

							return z_q







class __snake_case(				_lowerCAmelCase ):


						'''simple docstring'''



						def __init__( self     ,	A_     ,	A_=False				)     ->     int:
							lowerCAmelCase   =     parameters
							lowerCAmelCase,       lowerCAmelCase   =     torch.chunk(A_     ,	2     ,	dim=1				)
							lowerCAmelCase   =     torch.clamp(self.logvar     ,	-30.0     ,	20.0				)
							lowerCAmelCase   =     deterministic
							lowerCAmelCase   =     torch.exp(0.5 * self.logvar				)
							lowerCAmelCase   =     torch.exp(self.logvar				)
							if self.deterministic:
								lowerCAmelCase   =     lowerCAmelCase   =     torch.zeros_like(
								    self.mean     ,	device=self.parameters.device     ,	dtype=self.parameters.dtype				)


						def     __snake_case   ( self     ,	A_ = None				)     ->     torch.FloatTensor:
							# make sure sample is on the same device as the parameters and has same dtype
							lowerCAmelCase   =     randn_tensor(
							    self.mean.shape     ,	generator=A_     ,	device=self.parameters.device     ,	dtype=self.parameters.dtype				)
							lowerCAmelCase   =     self.mean + self.std * sample
							return x


						def     __snake_case   ( self     ,	A_=None				)     ->     Any:
							if self.deterministic:
								return torch.Tensor([0.0]				)
							else:
								if other is None:
									return 0.5 * torch.sum(torch.pow(self.mean     ,	2				) + self.var - 1.0 - self.logvar     ,	dim=[1, 2, 3]				)
								else:
									return 0.5 * torch.sum(
									    torch.pow(self.mean - other.mean     ,	2				) / other.var
									    + self.var / other.var
									    - 1.0
									    - self.logvar
									    + other.logvar     ,	dim=[1, 2, 3]     ,	)


						def     __snake_case   ( self     ,	A_     ,	A_=[1, 2, 3]				)     ->     str:
							if self.deterministic:
								return torch.Tensor([0.0]				)
							lowerCAmelCase   =     np.log(2.0 * np.pi				)
							return 0.5 * torch.sum(logtwopi + self.logvar + torch.pow(sample - self.mean     ,	2				) / self.var     ,	dim=A_				)




						def     __snake_case   ( self				)     ->     Optional[Any]:
							return self.mean




'''simple docstring'''

import numpy

class __snake_case:


						'''simple docstring'''



						def __init__( self     ,	A_     ,	A_				)     ->     None:
							lowerCAmelCase   =     input_array

							# Random initial weights are assigned where first argument is the
							# number of nodes in previous layer and second argument is the
							# number of nodes in the next layer.

							# Random initial weights are assigned.
							# self.input_array.shape[1] is used to represent number of nodes in input layer.
							# First hidden layer consists of 4 nodes.
							lowerCAmelCase   =     numpy.random.rand(
							    self.input_array.shape[1]     ,	4				)

							# Random initial values for the first hidden layer.
							# First hidden layer has 4 nodes.
							# Second hidden layer has 3 nodes.
							lowerCAmelCase   =     numpy.random.rand(
							    4     ,	3				)

							# Random initial values for the second hidden layer.
							# Second hidden layer has 3 nodes.
							# Output layer has 1 node.
							lowerCAmelCase   =     numpy.random.rand(3     ,	1				)

							# Real output values provided.
							lowerCAmelCase   =     output_array

							# Predicted output values by the neural network.
							# Predicted_output array initially consists of zeroes.
							lowerCAmelCase   =     numpy.zeros(output_array.shape				)


						def     __snake_case   ( self				)     ->     numpy.ndarray:
							lowerCAmelCase   =     sigmoid(
							    numpy.dot(self.input_array     ,	self.input_layer_and_first_hidden_layer_weights				)				)

							# layer_between_first_hidden_layer_and_second_hidden_layer is the layer
							# connecting the first hidden set of nodes with the second hidden set of nodes.
							lowerCAmelCase   =     sigmoid(
							    numpy.dot(
							        self.layer_between_input_and_first_hidden_layer     ,	self.first_hidden_layer_and_second_hidden_layer_weights     ,	)				)

							# layer_between_second_hidden_layer_and_output is the layer connecting
							# second hidden layer with the output node.
							lowerCAmelCase   =     sigmoid(
							    numpy.dot(
							        self.layer_between_first_hidden_layer_and_second_hidden_layer     ,	self.second_hidden_layer_and_output_layer_weights     ,	)				)

							return self.layer_between_second_hidden_layer_and_output


						def     __snake_case   ( self				)     ->     None:
							lowerCAmelCase   =     numpy.dot(
							    self.layer_between_first_hidden_layer_and_second_hidden_layer.T     ,	2
							    * (self.output_array - self.predicted_output)
							    * sigmoid_derivative(self.predicted_output				)     ,	)
							lowerCAmelCase   =     numpy.dot(
							    self.layer_between_input_and_first_hidden_layer.T     ,	numpy.dot(
							        2
							        * (self.output_array - self.predicted_output)
							        * sigmoid_derivative(self.predicted_output				)     ,	self.second_hidden_layer_and_output_layer_weights.T     ,	)
							    * sigmoid_derivative(
							        self.layer_between_first_hidden_layer_and_second_hidden_layer				)     ,	)
							lowerCAmelCase   =     numpy.dot(
							    self.input_array.T     ,	numpy.dot(
							        numpy.dot(
							            2
							            * (self.output_array - self.predicted_output)
							            * sigmoid_derivative(self.predicted_output				)     ,	self.second_hidden_layer_and_output_layer_weights.T     ,	)
							        * sigmoid_derivative(
							            self.layer_between_first_hidden_layer_and_second_hidden_layer				)     ,	self.first_hidden_layer_and_second_hidden_layer_weights.T     ,	)
							    * sigmoid_derivative(self.layer_between_input_and_first_hidden_layer				)     ,	)

							self.input_layer_and_first_hidden_layer_weights += (
							    updated_input_layer_and_first_hidden_layer_weights
							)
							self.first_hidden_layer_and_second_hidden_layer_weights += (
							    updated_first_hidden_layer_and_second_hidden_layer_weights
							)
							self.second_hidden_layer_and_output_layer_weights += (
							    updated_second_hidden_layer_and_output_layer_weights
							)


						def     __snake_case   ( self     ,	A_     ,	A_     ,	A_				)     ->     None:
							for iteration in range(1     ,	iterations + 1				):
								lowerCAmelCase   =     self.feedforward()
								self.back_propagation()
								if give_loss:
									lowerCAmelCase   =     numpy.mean(numpy.square(output - self.feedforward()				)				)
									print(f'Iteration {iteration} Loss: {loss}'				)




						def     __snake_case   ( self     ,	A_				)     ->     int:
							lowerCAmelCase   =     input_arr

							lowerCAmelCase   =     sigmoid(
							    numpy.dot(self.array     ,	self.input_layer_and_first_hidden_layer_weights				)				)

							lowerCAmelCase   =     sigmoid(
							    numpy.dot(
							        self.layer_between_input_and_first_hidden_layer     ,	self.first_hidden_layer_and_second_hidden_layer_weights     ,	)				)

							lowerCAmelCase   =     sigmoid(
							    numpy.dot(
							        self.layer_between_first_hidden_layer_and_second_hidden_layer     ,	self.second_hidden_layer_and_output_layer_weights     ,	)				)

							return int(self.layer_between_second_hidden_layer_and_output > 0.6				)







def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						numpy.ndarray							)      ->						numpy.ndarray:







	"""simple docstring"""
	return 1 / (1 + numpy.exp(-value							))






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						numpy.ndarray							)      ->						numpy.ndarray:







	"""simple docstring"""
	return (value) * (1 - (value))






def 		_snake_case		( )      ->						int:







	"""simple docstring"""
	lowerCAmelCase   =     numpy.array(
	    (
	        [0, 0, 0],
	        [0, 0, 1],
	        [0, 1, 0],
	        [0, 1, 1],
	        [1, 0, 0],
	        [1, 0, 1],
	        [1, 1, 0],
	        [1, 1, 1],
	    )							,		dtype=numpy.floataa							,		)

	# True output values for the given input values.
	lowerCAmelCase   =     numpy.array(([0], [1], [1], [0], [1], [0], [0], [1])							,		dtype=numpy.floataa							)

	# Calling neural network class.
	lowerCAmelCase   =     TwoHiddenLayerNeuralNetwork(
	    input_array=_SCREAMING_SNAKE_CASE							,		output_array=_SCREAMING_SNAKE_CASE							)

	# Calling training function.
	# Set give_loss to True if you want to see loss in every iteration.
	neural_network.train(output=_SCREAMING_SNAKE_CASE							,		iterations=10							,		give_loss=_SCREAMING_SNAKE_CASE							)

	return neural_network.predict(numpy.array(([1, 1, 1])							,		dtype=numpy.floataa							)							)


if __name__ == "__main__":
				example()