diff --git a/basic/basic_code.ipynb b/basic/basic_code.ipynb index 1267371..c23b504 100644 --- a/basic/basic_code.ipynb +++ b/basic/basic_code.ipynb @@ -560,7 +560,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -572,24 +572,74 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "a = torch.tensor([1.0, 1.5, 5.0], requires_grad=True)\n", + "print(a.requires_grad)\n", + "MyStraightBernoulli = StraightThroughBernoulli(a = a)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ - "MyStraightBernoulli = StraightThroughBernoulli(a = torch.tensor([1.0, 1.5, 5.0]))" + "# uniform = torch.distributions.Uniform(torch.tensor([0.0], device=a.device), torch.tensor([1.0], device=a.device))\n", + "uniform = torch.distributions.Uniform(torch.tensor([0.0]).to(a.device), torch.tensor([1.0]).to(a.device))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[0.5402],\n", + " [0.4525],\n", + " [0.5821],\n", + " [0.2611],\n", + " [0.6370]])" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "uniform.sample(torch.tensor([5]))" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "tensor([[False, False, False],\n", + " [False, False, False],\n", + " [False, False, False],\n", + " [False, False, False],\n", + " [False, False, False]])\n", + "False\n", "tensor([[0, 0, 0],\n", - " [1, 0, 0],\n", + " [0, 0, 0],\n", " [0, 0, 0],\n", " [0, 0, 0],\n", " [0, 0, 0]]) \n", @@ -623,7 +673,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -637,6 +687,9 @@ ], "source": [ "# Igor code\n", + "import os, sys\n", + "import torch\n", + "import matplotlib.pyplot as plt\n", "current_dir = os.getcwd()\n", "sys.path.append(os.path.abspath(os.path.join(current_dir, '..', 'src')))\n", "from relaxit.distributions import HardConcrete\n", @@ -647,27 +700,18 @@ }, { "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "MyHardConcrete = HardConcrete(alpha = torch.tensor(1.5) , beta = torch.tensor(5.8) , xi = torch.tensor(1.8), gamma = torch.tensor(-0.7))" - ] - }, - { - "cell_type": "code", - "execution_count": 22, + "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "tensor([[0.3002],\n", - " [0.6087],\n", - " [0.4846],\n", - " [0.4472],\n", - " [0.3865]]) \n", + "tensor([[0.4349],\n", + " [0.9231],\n", + " [0.5726],\n", + " [0.7604],\n", + " [0.5044]], grad_fn=) \n", "\n", "arg_constraints = {'alpha': GreaterThan(lower_bound=0.0), 'beta': GreaterThan(lower_bound=0.0), 'xi': GreaterThan(lower_bound=1.0), 'gamma': LessThan(upper_bound=0.0)}\n", "\n", @@ -676,6 +720,12 @@ } ], "source": [ + "alpha = torch.tensor(1.5, requires_grad=True) \n", + "beta = torch.tensor(5.8, requires_grad=True)\n", + "xi = torch.tensor(1.8 , requires_grad=True)\n", + "gamma = torch.tensor(-0.7 , requires_grad=True)\n", + "MyHardConcrete = HardConcrete(alpha= alpha , beta= beta , xi = xi , gamma = gamma)\n", + "\n", "print(MyHardConcrete.rsample(torch.tensor([5])), '\\n')\n", "print(f\"arg_constraints = {MyHardConcrete.arg_constraints}\\n\")\n", "print(f\"batch_shape = {MyHardConcrete.batch_shape}, event_shape = {MyHardConcrete.event_shape}\")" @@ -683,27 +733,82 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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WlCuJq/N2c8mU6mweORwcvizioiIlIDC03uj7TBNv379eOWVV8jMzKRJkya89dZbtGrV6qjbDxkyhKeffpp169Zx1lln8Z///IfLLrusyKGLzc61APzsns6H/svYbCqyyVRiK+Vw93ogw3I+ERGRElY4MmJxAmvIi9B/9dVX9OjRg969e7NgwQKaNGlCp06d2LJlyxG3nzFjBjfddBN33XUXCxcupGvXrnTt2pUlS5accPgTtjvYNua6dfnWbcd8U4csKuCGvltERESiUsDYnzMS8k/d119/nXvuuYc777yT+vXr079/f8qUKcPHH398xO3/+9//cumll/Loo49Sr149XnjhBZo3b87bb799wuFPWE6wjGSZcnZziIiIWDLMbQ+t7oOTKlrLENJhmvz8fObPn0+vXr0Kn/N4PHTs2JGZM2ce8TUzZ86kR48ehzzXqVMnRowYcdTPk5eXR15eXuHj7OxsAHJyckKJ++e2bIA8w4b8k3DdvcX7d4uIiESB1/Iu487zOgUfFPPP2YKf28aYY24XUhnZtm0bgUCAKlWqHPJ8lSpVWL58+RFfk5mZecTtMzOPfIosQJ8+fXjuuecOe75mzZqhxA3B6yX094qIiES+1DdL9u/fvXs3qampR/3ziDybplevXoeMpriuy44dOzjllFNwnOJbryMnJ4eaNWuyceNGUlK0+mlJ0X4OH+3r8NB+Dg/t5/Aoyf1sjGH37t1Ur179mNuFVEYqVqyI1+slK+vQC6ZkZWVRtWrVI76matWqIW0PkJycTHLyoVekLVeuXChRQ5KSkqJv9DDQfg4f7evw0H4OD+3n8Cip/XysEZECIU1gTUpKokWLFkycOLHwOdd1mThxIm3atDnia9q0aXPI9gATJkw46vYiIiISX0I+TNOjRw9uv/12WrZsSatWrXjzzTfJzc3lzjvvBKBbt27UqFGDPn36APDQQw9xwQUX8Nprr9GlSxcGDx7MvHnzeP/994v3KxEREZGoFHIZueGGG9i6dSvPPPMMmZmZNG3alLFjxxZOUt2wYQMez8EBl7Zt2/Lll1/y1FNP8cQTT3DWWWcxYsQIGjZsWHxfRRElJyfTu3fvww4JSfHSfg4f7evw0H4OD+3n8IiE/eyYPzvfRkRERKQEaalRERERsUplRERERKxSGRERERGrVEZERETEqpgvI/369SMtLY1SpUrRunVr5syZc8zthwwZQt26dSlVqhSNGjVizJgxYUoa3ULZzx988AHt27enfPnylC9fno4dO/7pv4scFOr3dIHBgwfjOA5du3Yt2YAxItT9vGvXLrp37061atVITk7m7LPP1vvHcQh1P7/55pvUqVOH0qVLU7NmTR555BH2798fprTRaerUqVxxxRVUr14dx3GOeW24ApMnT6Z58+YkJydz5plnMmDAgJINaWLY4MGDTVJSkvn444/N0qVLzT333GPKlStnsrKyjrj9Tz/9ZLxer3n55ZfNL7/8Yp566imTmJhoFi9eHObk0SXU/XzzzTebfv36mYULF5ply5aZO+64w6SmpppNmzaFOXn0CXVfF1i7dq2pUaOGad++vbnqqqvCEzaKhbqf8/LyTMuWLc1ll11mpk+fbtauXWsmT55s0tPTw5w8uoS6n7/44guTnJxsvvjiC7N27Vozbtw4U61aNfPII4+EOXl0GTNmjHnyySfNsGHDDGCGDx9+zO3XrFljypQpY3r06GF++eUX89Zbbxmv12vGjh1bYhljuoy0atXKdO/evfBxIBAw1atXN3369Dni9tdff73p0qXLIc+1bt3a3HfffSWaM9qFup//yO/3m7Jly5pPP/20pCLGjKLsa7/fb9q2bWs+/PBDc/vtt6uMHIdQ9/O7775rzjjjDJOfnx+uiDEh1P3cvXt385e//OWQ53r06GHatWtXojljyfGUkccee8w0aNDgkOduuOEG06lTpxLLFbOHafLz85k/fz4dO3YsfM7j8dCxY0dmzpx5xNfMnDnzkO0BOnXqdNTtpWj7+Y/27t2Lz+ejQoUKJRUzJhR1Xz///PNUrlyZu+66Kxwxo15R9vO3335LmzZt6N69O1WqVKFhw4a89NJLBAKBcMWOOkXZz23btmX+/PmFh3LWrFnDmDFjuOyyy8KSOV7Y+FkYkVftLQ7btm0jEAgUrgxboEqVKixfvvyIr8nMzDzi9pmZmSWWM9oVZT//0eOPP0716tUP++aXQxVlX0+fPp2PPvqI9PT0MCSMDUXZz2vWrGHSpEnccsstjBkzhlWrVvHAAw/g8/no3bt3OGJHnaLs55tvvplt27Zx3nnnYYzB7/fz97//nSeeeCIckePG0X4W5uTksG/fPkqXLl3snzNmR0YkOvTt25fBgwczfPhwSpUqZTtOTNm9eze33XYbH3zwARUrVrQdJ6a5rkvlypV5//33adGiBTfccANPPvkk/fv3tx0tpkyePJmXXnqJd955hwULFjBs2DBGjx7NCy+8YDuanKCYHRmpWLEiXq+XrKysQ57PysqiatWqR3xN1apVQ9peirafC7z66qv07duXH374gcaNG5dkzJgQ6r5evXo169at44orrih8znVdABISElixYgW1a9cu2dBRqCjf09WqVSMxMRGv11v4XL169cjMzCQ/P5+kpKQSzRyNirKfn376aW677TbuvvtuABo1akRubi733nsvTz755CHXRZOiO9rPwpSUlBIZFYEYHhlJSkqiRYsWTJw4sfA513WZOHEibdq0OeJr2rRpc8j2ABMmTDjq9lK0/Qzw8ssv88ILLzB27FhatmwZjqhRL9R9XbduXRYvXkx6enrh7corr+TCCy8kPT2dmjVrhjN+1CjK93S7du1YtWpVYdkD+PXXX6lWrZqKyFEUZT/v3bv3sMJRUACNLrNWbKz8LCyxqbERYPDgwSY5OdkMGDDA/PLLL+bee+815cqVM5mZmcYYY2677TbTs2fPwu1/+uknk5CQYF599VWzbNky07t3b53aexxC3c99+/Y1SUlJ5ptvvjEZGRmFt927d9v6EqJGqPv6j3Q2zfEJdT9v2LDBlC1b1jz44INmxYoVZtSoUaZy5crmxRdftPUlRIVQ93Pv3r1N2bJlzaBBg8yaNWvM+PHjTe3atc31119v60uICrt37zYLFy40CxcuNIB5/fXXzcKFC8369euNMcb07NnT3HbbbYXbF5za++ijj5ply5aZfv366dTeE/XWW2+ZWrVqmaSkJNOqVSsza9aswj+74IILzO23337I9l9//bU5++yzTVJSkmnQoIEZPXp0mBNHp1D282mnnWaAw269e/cOf/AoFOr39O+pjBy/UPfzjBkzTOvWrU1ycrI544wzzL///W/j9/vDnDr6hLKffT6fefbZZ03t2rVNqVKlTM2aNc0DDzxgdu7cGf7gUeTHH3884ntuwb69/fbbzQUXXHDYa5o2bWqSkpLMGWecYT755JMSzegYo7EtERERsSdm54yIiIhIdFAZEREREatURkRERMQqlRERERGxSmVERERErFIZEREREatURkRERMQqlRERERGxSmVERERErFIZEREREatURkRERMQqlRERERGx6v8Bf1H+7I8/8pEAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], + "source": [ + "alphas = torch.linspace(0.01,100,10)\n", + "for alpha in alphas:\n", + " print(f'ALPHA = {alpha}')\n", + " MyHardConcrete = HardConcrete(alpha = alpha , beta = torch.tensor(5.8) , xi = torch.tensor(1.8), gamma = torch.tensor(-0.7))\n", + "\n", + " samples = MyHardConcrete.rsample(torch.tensor([100000]))[:,0]\n", + " x = torch.linspace(0,1,1000)\n", + " plt.hist(samples, bins=100 , density = True)\n", + " plt.plot(x , torch.exp(MyHardConcrete.log_prob(x)))\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "samples = MyHardConcrete.rsample(torch.tensor([100000]))[:,0]\n", - "x = torch.linspace(0,1,1000)\n", - "plt.hist(samples, bins=100 , density = True)\n", - "plt.plot(x , torch.exp(MyHardConcrete.log_prob(x)))\n", - "plt.show()" + "betas = torch.linspace(0.01,100,10)\n", + "for beta in betas:\n", + " print(f'BETA= {beta}')\n", + " MyHardConcrete = HardConcrete(alpha = torch.tensor(1.5) , beta = beta , xi = torch.tensor(1.8), gamma = torch.tensor(-0.7))\n", + "\n", + " samples = MyHardConcrete.rsample(torch.tensor([100000]))[:,0]\n", + " x = torch.linspace(0,1,1000)\n", + " plt.hist(samples, bins=100 , density = True)\n", + " plt.plot(x , torch.exp(MyHardConcrete.log_prob(x)))\n", + " plt.show()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "xis = torch.linspace(1.01,3,10)\n", + "for xi in xis:\n", + " print(f'XI= {xi}')\n", + " MyHardConcrete = HardConcrete(alpha = torch.tensor(1.5) , beta = torch.tensor(5.8) , xi = xi, gamma = torch.tensor(-0.7))\n", + "\n", + " samples = MyHardConcrete.rsample(torch.tensor([100000]))[:,0]\n", + " x = torch.linspace(0,1,1000)\n", + " plt.hist(samples, bins=100 , density = True)\n", + " plt.plot(x , torch.exp(MyHardConcrete.log_prob(x)))\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gammas = -torch.linspace(0.01,3,10)\n", + "for gamma in gammas:\n", + " print(f'gamma= {gamma}')\n", + " MyHardConcrete = HardConcrete(alpha = torch.tensor(1.5) , beta = torch.tensor(5.8) , xi = torch.tensor(1.8), gamma = gamma)\n", + "\n", + " samples = MyHardConcrete.rsample(torch.tensor([100000]))[:,0]\n", + " x = torch.linspace(0,1,1000)\n", + " plt.hist(samples, bins=100 , density = True)\n", + " plt.plot(x , torch.exp(MyHardConcrete.log_prob(x)))\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -722,7 +827,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.15" + "version": "3.10.12" } }, "nbformat": 4, diff --git a/demo/vae_hard_concrete.py b/demo/vae_hard_concrete.py index b48b57d..9b99baa 100644 --- a/demo/vae_hard_concrete.py +++ b/demo/vae_hard_concrete.py @@ -15,7 +15,7 @@ parser = argparse.ArgumentParser(description='VAE MNIST Example') parser.add_argument('--batch-size', type=int, default=128, metavar='N', help='input batch size for training (default: 128)') -parser.add_argument('--epochs', type=int, default=10, metavar='N', +parser.add_argument('--epochs', type=int, default=20, metavar='N', help='number of epochs to train (default: 10)') parser.add_argument('--no-cuda', action='store_true', default=False, help='enables CUDA training') @@ -58,11 +58,15 @@ def __init__(self): def encode(self, x): h1 = F.relu(self.fc1(x)) - alpha = torch.exp(self.fc21(h1)) # alpha > 0 - beta = torch.exp(self.fc22(h1)) # beta > 0 + # alpha = torch.exp(self.fc21(h1)) # alpha > 0 + alpha = torch.clamp(self.fc21(h1) , min = torch.tensor(1e-5) ,max = torch.tensor(100) ) + # beta = torch.exp(self.fc22(h1)) # beta > 0 + beta = torch.clamp(self.fc22(h1) , min = torch.tensor(1e-5) ,max = torch.tensor(1000) ) # Почему-то не выполняется условие xi > 1 сели добавлять ровно 1.0 - xi = torch.exp(self.fc23(h1)) + torch.tensor([1.0 + 1e-5], device=device) # xi > 1.0 - gamma = -torch.exp(self.fc24(h1)) # gamma < 0.0 + # xi = torch.exp(self.fc23(h1)) + torch.tensor([1.0 + 1e-5], device=device) # xi > 1.0 + xi = torch.clamp(self.fc23(h1) , min = torch.tensor(1 + 1e-5) ,max = torch.tensor(3) ) + # gamma = - torch.exp(self.fc24(h1)) # gamma < 0.0 + gamma = torch.clamp(self.fc24(h1), min = torch.tensor(-3) ,max = torch.tensor(-1e-5) ) return alpha, beta, xi, gamma def decode(self, z): @@ -72,7 +76,9 @@ def decode(self, z): def forward(self, x, hard=False): alpha, beta, xi, gamma = self.encode(x.view(-1, 784)) q_z = HardConcrete(alpha=alpha, beta=beta, xi=xi, gamma=gamma) + z = q_z.rsample() # sample with reparameterization + # log_probs = q_z.log_prob(z) if hard: # No step function in torch, so using sign instead @@ -80,6 +86,7 @@ def forward(self, x, hard=False): z = z + (z_hard - z).detach() return self.decode(z), z + # return self.decode(z), log_probs model = VAE().to(device) diff --git a/demo/vae_straight_through_bernoulli.py b/demo/vae_straight_through_bernoulli.py index 5d641d8..f7a52db 100644 --- a/demo/vae_straight_through_bernoulli.py +++ b/demo/vae_straight_through_bernoulli.py @@ -62,9 +62,17 @@ def decode(self, z): return torch.sigmoid(self.fc4(h3)) def forward(self, x, hard=False): - a = self.encode(x.view(-1, 784)).float() + a = self.encode(x.view(-1, 784)) + # print(a.requires_grad) + a = a.float() + # print(a.requires_grad)) + q_z = StraightThroughBernoulli(a) - z = q_z.rsample().float() # sample with reparameterization + + z = q_z.rsample() + # print(z.requires_grad ) + z = z.float() # sample with reparameterization + # raise Exception('TEST') if hard: # No step function in torch, so using sign instead diff --git a/src/relaxit/distributions/StraightThroughBernoulli.py b/src/relaxit/distributions/StraightThroughBernoulli.py index d77f9a7..fe55e44 100644 --- a/src/relaxit/distributions/StraightThroughBernoulli.py +++ b/src/relaxit/distributions/StraightThroughBernoulli.py @@ -55,8 +55,10 @@ def rsample(self, sample_shape: torch.Size = torch.Size()) -> torch.Tensor: Returns: - torch.Tensor: A sample from the distribution. """ - eps = self.uniform.sample(sample_shape) + eps = self.uniform.sample(sample_shape).to(self.a.device) + print(eps > torch.nn.functional.sigmoid(self.a)) z = torch.where(eps > torch.nn.functional.sigmoid(self.a), 1, 0) + print(z.requires_grad) return z def sample(self, sample_shape: torch.Size = torch.Size()) -> torch.Tensor: